AcWing 25. 剪绳子(dp)

博客探讨了一个使用动态规划解决的问题:如何在必须将绳子切成至少两段的情况下,最大化每段绳子长度的乘积。作者首先尝试了一个解决方案,但发现对于2和3的特殊情况需要特殊处理。然后,他们修正了状态转移方程,以确保正确考虑所有情况,最终得出一个通用的动态规划解决方案。
摘要由CSDN通过智能技术生成

题目链接
在这里插入图片描述

class Solution {
public:
    int maxProductAfterCutting(int length) {
        int ans=-1;
        //感觉有点dp的味道
        //每个位置断的话,最大就是左右两边的最大值乘积
        int dp[60];//dp[i]表示长度为i的绳子裁剪得到的最大乘积
        dp[0]=0;
        dp[1]=1;
        dp[2]=2;
        for(int i=3;i<=length;i++){
            int tmp=i;//不分割
            for(int j=1;j<i;j++){
                tmp=max(tmp,dp[j]*dp[i-j]);
            }
            dp[i]=tmp;
        }
        dp[2]=1;//至少要分成2段
        dp[3]=2;//至少要分成2段
        //dp[4]之后都不会是length本身是最大值
        return dp[length];
    }
};

自己写的dp对于2和3的情况需要特判,对于≥4之后的绳子,是切割之后能得到最大值,对于2和3,不切才是最大,但是题目要求至少切为2段,因此递推后面的dp[i]时用的dp[2]=2,dp[3]=3,最后再重新赋值回正确答案。
这样不统一的本质原因是理解成了1-i中在j处切一刀之后的最值是两段绳子各自至少2次切割的最大值,也就是用dp[j]*dp[i-j],事实上对于2和3而言,不切割才会是最大的,即 dp[2]=1,dp[3]=2是必须切一刀之后的最大值,对于后面用到2和3,用本身的2和3才对,转化一下状态转移方程就是下面的了
在这里插入图片描述
受此启发,其实就是对于0-i,在j处切割之后,左边取不切与切两种选择的最大值,右边取不切与切两种选择最大值,两者乘积就是在j处切割所能达到的最大值了。

class Solution {
public:
    int maxProductAfterCutting(int length) {
        int ans=-1;
        //感觉有点dp的味道
        //每个位置断的话,最大就是左右两边的最大值乘积
        int dp[60]={0};//dp[i]表示长度为i的绳子裁剪得到的最大乘积
        for(int i=2;i<=length;i++){
            for(int j=1;j<i;j++){
                dp[i]=max(dp[i],max(j,dp[j])*max(i-j,dp[i-j]));
            }
        }
        return dp[length];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值