动态规划总结

动态规划

核心思想:

将大问题划分小问题去解决,就是将历史数据存起来的一种算法,而存历史数据的就是数组,可以是一维,也可以是二维。

三大步骤:

步骤一:定义数组dp[i](或dp[i][j])是什么含义,一般求什么设什么。

步骤二:寻找数组元素间的关系推导式,换句话说,dp[i]是由dp[i-1]或dp[i-2]如何转换而来。例如dp[i][j]一定与dp[i-1][j-1],dp[i][j-1],dp[i-1][j]有关系。这一步是最难的。

步骤三:数组初始化,也就是边界初始化。因为后面的dp[n]由前面的推导而来,首先要赋值初始值才能得出结果。

案例一:

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

分析:

定义dp[i] 为爬上i阶的路径,dp[i]可以由i-1阶或i-2阶跳上来。初始化dp[1]=dp[0]=1;跳上1或0阶路径为1.

代码实现:

dp[1]=dp[0]=1;
       for(int i=2;i<=n;i++)
        dp[i]=dp[i-2]+dp[i-1];

案例二:

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/house-robber

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:

定义dp[i]为打劫所获取的最大金额。dp[i]由是打劫前一个房屋(dp[i-1])和是打劫当前房屋(dp[i-2]+nums[i])推导而来,值得注意的是要进行特判,最开始打劫第一个,还是第二个。初始化dp[0]=nums[0].

代码实现:

dp[0]=nums[0];
        int n=nums.size();
        for(int i=1;i<n;i++){
            if(i==1)
            dp[1]=max(nums[0],nums[1]);
            else{
                dp[i]=max(dp[i-1],dp[i-2]+nums[i]);
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值