15.1 鋼條切割(動態規劃)
阿新 • • 發佈:2019-01-01
問題:
給定一段長度為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];
}