动态规划java版

动态规划java版本


模版

labuladong动态规划算法小抄

1、确定 base case,这个很简单,基础目标赋值;

2、确定「状态」,也就是原问题和子问题中会变化的变量。所以唯一的「状态」就是目标变量

3、确定「选择」,也就是导致「状态」产生变化的行为。目标如何变化,就是按照什么规则变化就是你的「选择」。

4、明确 dp 函数/数组的定义。我们这里讲的是自顶向下的解法,所以会有一个递归的 dp 函数,一般来说函数的参数就是状态转移中会变化的量,也就是上面说到的「状态」;函数的返回值就是题目要求我们计算的量。
# 初始化 base case
dp[0][0][...] = base
# 进行状态转移
for 状态1 in 状态1的所有取值:
    for 状态2 in 状态2的所有取值:
        for ...
            dp[状态1][状态2][...] = 求最值(选择1,选择2...)

案例1

剑指 Offer 14- I. 剪绳子

给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]*k[1]*...*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为233的三段,此时得到的最大乘积是18。

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1

示例 2:

输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

提示:

    2 <= n <= 58

套入模版

class Solution {
    public int cuttingRope(int n) {
        //为什么要这么写呢,是因为如果写成new int[n]的话,包含项0-n-1,而我们所求要直接到n所以写成new int[n+1]表示0-n;
        int[] dp = new int[n+1];
        //base case 确定base
        dp[2]=1;
        //从三开始,因为要从二开始切,从一开始切对乘积没有贡献
        for(int i=3;i<n+1;i++){
            for(int j=2;j<i;j++){
                //状态转移方程
                // 剪了第一段后,剩下(i - j)长度可以剪也可以不剪。如果不剪的话长度乘积即为j * (i - j);如果剪的话长度乘积即为j * dp[i - j]。取两者最大值max(j * (i - j), j * dp[i - j])
                dp[i] = Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]));
            }
        }
        return dp[n];


    }
}

总结

状态转移公式确定很难很难,多刷多做!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值