剪绳子问题and leetcode343

参考剑指offer上的剪绳子问题,其中动态规划的方法有一部分我不是很理解,这里引用一下别人的部分代码。

public class Test {
    public static void main(String[] args) {
        int len = 10;
        System.out.println(maxLen(len));
    }
    /**
     * @param len绳子的长度
     * @return
     */
    private static double maxLen(int len) {
        // lenCut[i]表示长度为i个的最优解 lenCut[3]比较特殊
        double lenCut[] = new double[len + 1];
        lenCut[0] = 0;
        lenCut[1] = 1;
        lenCut[2] = 2;
        lenCut[3] = 3;
        //初始化到3是因為3>1*2,其本身比分割的大,所以當分割比3大的數字時候,如5可以分成2,3,3就不繼續往下分割了
        if (len < 2) {
            return 0;
        } else if (len == 2) {
            return 1;
        } else if (len == 3) {
            return 2;
        } else {
            for (int i = 4; i <= len; i++) {
                double max = 0;
                for (int j = 1; j <= i / 2; j++) {
                    double temp = lenCut[j] * lenCut[i - j];
                    if (max < temp) {
                        max = temp;
                    }
                }
                lenCut[i] = max;
            }
        }
        return lenCut[len];
    }
} 

其实我不是很理解这里的lenCut[3]=3.因为按照书上的思路对应的lenCut[3]对应的应该是长度为4时,可分割的最大长度,所以这里应该是4.

经过研究,我从另外一个角度来思考这个问题。将长度为n的绳子分为1与n-1是收益最低的,所以最短的且收益较大的需要从2开始考虑。同理3也是可以的,到4,可以分为2和2的情况,所以,在从上往下的递归思路中,收益最大的情况叶子节点是由2和3组成的,所以,在递归改为dp的时候,只需要存dp[2]和dp[3]即可。代表着长度为2和长度为3时不必继续分下去了。所以我的代码如下

class Solution {
    public int integerBreak(int n) {
        if(n<2){
            return 0;
        }
        if(n==2) return 1;
        if(n==3) return 2;
        int []dp=new int[n+1];
        dp[2]=2;
        dp[3]=3;
        int max=0;
        for(int i=4;i<=n;i++){
            dp[i]=Math.max(dp[i-2]*dp[2],dp[i-3]*dp[3]);
        }
        return dp[n];
    }
}

我倒是觉得这个思路从一定程度上可以解释为什么最开始的代码里dp[3]=3了吧。一家之言。望大佬们指正。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值