• 代码随想录第45天|70. 爬楼梯,322. 零钱兑换,279.完全平方数


     

    70. 爬楼梯

    开始按感觉做

    1. class Solution {
    2. public int climbStairs(int n) {
    3. //第一版按感觉做
    4. //dp[i]爬到第i个台阶的方法数
    5. int[] dp=new int[n+1];
    6. //初始化
    7. dp[0]=1;
    8. dp[1]=1;
    9. for(int i=2;i<=n;i++){
    10. dp[i]=dp[i-1]+dp[i-2];
    11. }
    12. return dp[n];
    13. }
    14. }

    改进-用完全背包做

    这是背包里求排列问题,即:1、2 步 和 2、1 步都是上三个台阶,但是这两种方法不一样!

    需要先遍历背包再遍历物品

    1. class Solution {
    2. public int climbStairs(int n) {
    3. //用完全背包做
    4. //dp[i]爬到第i个台阶的方法数
    5. int[] dp=new int[n+1];
    6. int m = 2; //有兩個物品:itme1重量爲一,item2重量爲二
    7. //初始化
    8. dp[0]=1;
    9. for(int j=1;j<=n;j++){//遍历背包
    10. for(int i=1;i<=m;i++){//遍历物品
    11. if(j>=i){
    12. dp[j]+=dp[j-i];
    13. }
    14. }
    15. }
    16. return dp[n];
    17. }
    18. }

    322. 零钱兑换

    也是一个完全背包问题,但要注意和518.零钱兑换II的区别,

    动规五部曲分析如下:

    1.确定dp数组以及下标的含义

    dp[j]:凑足金额为j所需钱币的最少个数

    2.确定递推公式

    凑足金额为j-coins[i]的最少个数是dp[j-coins[i]],那么只需加上一个钱币coins[i]即dp[j-coins[i]]+1就是dp[j],所以dp[j]要取所以dp[j-coins[i]]+1中最小的。递推公式:dp[j]=min(dpp[j-coins[i]]+1,dp[j]);

    3.dp数组如何初始化

    凑足总金额为0需要的钱币个数一定是0,那么dp[0]=0

    其他下标应该初始化为INT_MAX,否则就会在min(dpp[j-coins[i]]+1,dp[j])比较的过程中被初始值覆盖。所以下标非-元素都应该是最大值。

    4.遍历顺序

    都可以,因为本题求的是最小个数,于集合是组合还是排列没有关系

    5.推导dp

    先遍历物品再遍历背包,dp[amount]是最终结果

    代码实现

    1. class Solution {
    2. public int coinChange(int[] coins, int amount) {
    3. //完全背包
    4. //dp[i]表示凑成金额为i所需的最少硬币个数
    5. int[] dp=new int[amount+1];
    6. dp[0]=0;
    7. for(int i=1;i<dp.length;i++){
    8. dp[i]=Integer.MAX_VALUE;
    9. }
    10. for(int i=0;i<coins.length;i++){
    11. for(int j=coins[i];j<=amount;j++){
    12. // if(coins[i]<=j){
    13. if (dp[j - coins[i]] != Integer.MAX_VALUE) {//如果是dp[j - coins[i]等于Integer.MAX_VALUE,那么+1后溢出,变成-2147483648
    14. dp[j]=Math.min(dp[j],dp[j-coins[i]]+1);
    15. }
    16. }
    17. }
    18. return dp[amount]>amount?-1:dp[amount];
    19. //或者return dp[amount]==Integer.MAX_VALUE?-1:dp[amount];
    20. }
    21. }

     这道题的时候卡住了,一开始在for循环里面是写的if(coins[i]<=j)这个条件,然后出现下面用例报错: 后面优化成 if (dp[j - coins[i]] != Integer.MAX_VALUE)

     

    279.完全平方数

    这道题和322. 零钱兑换思路基本一致

    1.dp的定义

    dp[i]表示组成和为i的最少完全平方数个数

    2.初始化

    组成0的最少完全平方数个数是0,其他非0下标初始化为最大数Integer.MAX_VALUE

    3.递推公式

     dp[j]=Math.min(dp[j],dp[j-i*i]+1); 

    4.遍历顺序

    这道题要求的是最少和排列还是组合没有关系,因此先遍历背包还是先遍历物品都是可以的

    5.推导dp

    代码实现

    1. class Solution {
    2. public int numSquares(int n) {
    3. //dp[i]含义:组成和为i的完全平方数的最少数量
    4. int[] dp=new int[n+1];
    5. //初始化
    6. dp[0]=0;//组成和为0的完全平方数是0
    7. for(int i=1;i<dp.length;i++){
    8. dp[i]=Integer.MAX_VALUE;
    9. }
    10. //
    11. for(int i=1;i*i<=n;i++){//遍历物品
    12. for(int j=i*i;j<=n;j++){//遍历背包
    13. if(j>=i*i&&dp[j-i*i]!=Integer.MAX_VALUE){//这个条件加不加都可以过
    14. dp[j]=Math.min(dp[j],dp[j-i*i]+1);
    15. }
    16. }
    17. }
    18. return dp[n];
    19. }
    20. }

  • 相关阅读:
    如何基于Security框架兼容多套用户密码加密方式
    MongoDB 基础了解(一)
    C/C++教程 从入门到精通《第十八章》—— MFC制作视频播放器
    FTPS: 500 OOPS priv_sock_get_result
    验收材料-软件质量保证措施
    基于kolla的openstack在线变更网卡(bond)
    Spring注解处理机制
    git原理和命令以及工具
    HAproxy负载均衡集群
    使用vue-cli搭建SPA项目
  • 原文地址:https://blog.csdn.net/m0_67042480/article/details/132784159