1. 程式人生 > >15.1 鋼條切割(動態規劃)

15.1 鋼條切割(動態規劃)

問題:
給定一段長度為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]; }