如何修改cutRod和bottomUpCutRod方法以保存大于数组长度的长度。例如,当前p的长度为11,如何切割具有相同阵列的长度为15,20的杆等。例如
p = {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
如果我调用cutRod(p,10),我得到30,但它当然在cutRod(p,15)或者崩溃 cutRod(P,20)。 (同样适用于bottomUpCutRod)。任何想法如何做到这一点?这是动态编程问题,我实现bottomUpCutRod方法的想法是遍历p,并且每个元素计算自身及其邻居的每个排列,并在必要时更新结果数组r。
public class Main {
private static final double MINUS_INFINITY = Double.NEGATIVE_INFINITY;
public static void main(String[] args) {
// price array
double[] p = {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
// test cutRod
cutRod(p,10);
// test bottomUpCutRod
bottomUpCutRod(p,10);
}//end of main
// an optimal cut for a rod of length n
// p is the price array
// use recursion
private static double cutRod(double[] p, int value) {
double[] r = new double[value+1];
double out = 0;
// initialize r to NEGATIVE_INFINITY;
for (int i = 1; i < r.length; i++)
r[i] = MINUS_INFINITY;
// call the helper method
out = helpCutRod(p,r.length-1,r);
// print r
System.out.println("Result ");
System.out.println("r[" + (r.length-1) + "] = " + r[r.length-1]);
return out;
}//end of method
// helpCutRod computes an optimal cut for a rod
// p is the price array and r[i] is the optimal cut for a rod of length i
// n is the length of the rod that is currently being computed
private static double helpCutRod(double[] p, int n, double[] r) {
double q = MINUS_INFINITY;
if (r[n] >= 0) // the whole r was computed
return r[n];
if (n == 0)
q = 0;
else {
for (int i = 1; i <= n; i++) {
q = RodCutting.max(q, p[i] + helpCutRod(p,n-i,r));
}
r[n] = q;
}
return q;
}
// use the bottom-up approach
// do NOT use recursion
private static double bottomUpCutRod(double[] p, int len) {
// r[i] is the optimal cut for a rod of length i
double[] r = new double[len+1];
r[0] = 0;
for (int j = 1; j < p.length; j++) {
// compute r[j]
double q = MINUS_INFINITY;
// r[j] is the maximum over i of p[i] + r[j-i]
// where 1<= i <= j
for (int i = 1; i <= j; i++)
q = max(q, p[i] + r[j-i]);
// update value of r[j]
r[j] = q;
}//end of for outer
// print r
System.out.println("The r array from the bottomUpCutRod:");
System.out.println("r[" + len + "] = " + r[len]);
return r[len] ;
}//end of method
public static double max(double a, double b){
if(a<=b){
return b;
}else{
return a;
}
}//end of max
}//end of class
答案 0 :(得分:0)
如果我正确理解了杆切割问题,那么您的价格数组p
会告诉您可以通过p.length - 1
销售长度为0的杆件的价格。因此,如果阵列长度为11,即使您有一个长度为15,20或30的初始杆,您也知道长度为10的碎片价格。由于您不知道11号及以上长度的价格,我假设您可以安全地将它们设置为0.我会期望算法将你的杆切成碎片,你知道它是正价格。
如果所有这些都是正确的,那么解决方案很简单。比如,cutRod(p, 15)
计算,首先要做
p = Arrays.copyOf(p, 15 + 1);
这会将p
复制到索引为0到15的新数组中,并用zeores填充。现在运行你的方法。当然,与其他初始长度类似。
通过此修改,您的程序将打印杆长度为15:
Result
r[15] = 43.0
The r array from the bottomUpCutRod:
r[15] = 43.0
我认为它在10,3和2处被发现产生价格30 + 8 + 5 = 43,但我没有检查过。
编辑:如果杆比价格数组长得多,那么计算结果时切割的时间长于价格数组的最大值可能是浪费。因此,实际上可以修改您的方法以接受更短的价格数组和更长的初始棒。而不是上面的快速修复。
在递归helpCutRod()
中,将for循环更改为:
for (int i = 1; i <= Math.min(n, p.length - 1); i++) {
这将确保只考虑我们有价格的作品。
对于bottomUpCutRod()
,需要进行两项更改:
第一个for循环需要运行,直到j
等于len
:
for (int j = 1; j < r.length; j++) {
同样,内部for循环不应该通过p
:
for (int i = 1; i <= Math.min(j, p.length - 1); i++)
使用这三个修改而不是p
数组的扩展,程序将打印与上面相同的结果。