问题:
给定一段长度为n英寸的钢条和一个价格表,求切割钢条方案,使收益最大(切割本身没有成本)。
解法一(带备忘录的自顶向下法):
/***
* 带备忘录的自顶向下法
* @param p 长度为i的钢条的收益为p[i]
* @param n 待切割的钢条的长度
*/
public static int memoizedCutRod(int[] p,int n) {
//备忘录,记录长度为i的钢条的最优切割的收益为r[i]
int[] r=new int[n+1];
for (int i = 0; i <= n; i++) {
r[i]=-1; //初始化为-1,表示没有收益
}
return memoizedCutRodAux(p,n,r);
}
private static int memoizedCutRodAux(int[] p,int n,int[] r) {
if (r[n] >= 0) {
//判断所需的值是否已经求过
return r[n];
}
int q=-1;
if (n==0) {
q=0;
}else {
for (int i = 1; i <= n; i++) {
q=Math.max(q, p[i]+memoizedCutRodAux(p,n-i,r));
}
}
r[n]=q;
return q;
}
解法二(自底向上法):
/***
* 自底向上法
* @param p 长度为i的钢条的收益为p[i]
* @param n 待切割的钢条的长度
* @return
*/
public static int bottomUpCutRod(int[] p,int n) {
//记录长度为i的钢条的最优切割的收益为r[i]
int[] r=new int[n+1];
r[0]=0; //长度为0的钢条没有收益
int q=-1;
for (int i = 1; i <= n; i++) {
q=-1;
for (int j = 1; j <= i; j++) {
q=Math.max(q, p[j]+r[i-j]);
}
r[i]=q;
}
return r[n];
}