当前位置: 首页 > article >正文

代码随想录算法训练营 ---第四十五天

前言:

 昨天的题做过之后,今天的题基本上都很简单,但是要注重一下细节。

第一题:

简介:

动态规划五部曲:

1.确定dp数组的含义

   dp[i]:爬到有i个台阶的楼顶,有dp[i]种方法

2.确定dp公式

    i:可以看作本次的物品值

    j:可以看作背包容量

    dp[j] +=dp[j-i];

3.确定如何初始化dp数组

    dp[0] = 1;

4.确定如何遍历数组

   先遍历背包,再遍历物品(因为我们先迈一步再迈两步 还是 先迈两步再迈一步 是有区别的)

 for(int j=0;j<=n;j++){
        for(int i=1;i<=m;i++){
            if(j-i>=0)
            dp[j] +=dp[j-i];
        }
    }

5.打印数组,看是否正确

代码实现:

#include <iostream>
#include <vector>
using namespace std;

int palou(int m,int n){
    vector<int> dp(n+1,0);
    dp[0] = 1;
    for(int j=0;j<=n;j++){
        for(int i=1;i<=m;i++){
            if(j-i>=0)
            dp[j] +=dp[j-i];
        }
    }
    return dp.back();
}


int main(){
   int m,n;
   cin>>n>>m;
   cout<<palou(m,n);
   return 0;
}

第二题:

简介:

我认为本题的重点在于如何初始化dp数组,自己做时在那里吃了亏。

动规五部曲分析如下:

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

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

     2.确定递推公式                                                                                                                                     递推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);  如果放入就加一个金币,不放入就不加。

     3.dp数组如何初始化                                                                                                                              首先凑足总金额为0所需钱币的个数一定是0,那么dp[0] = 0;然后考虑到递推公式的特性,dp[j]必须初始化为一个最大的数,否则就会在min(dp[j - coins[i]] + 1, dp[j])比较的过程中被初始值覆盖。所以下标非0的元素都是应该是最大值。

代码如下:

vector<int> dp(amount + 1, INT_MAX);
dp[0] = 0;

  4.确定遍历顺序

        本题求钱币最小个数,那么钱币有顺序和没有顺序都可以,都不影响钱币的最小个数。所以本题并不强调集合是组合还是排列。如果求组合数就是外层for循环遍历物品,内层for遍历背包如果求排列数就是外层for遍历背包,内层for循环遍历物品所以本题的两个for循环的关系是:外层for循环遍历物品,内层for遍历背包或者外层for遍历背包,内层for循环遍历物品都是可以的!

5.举例推导dp数组

322.零钱兑换

dp[amount]为最终结果。 

代码实现:

    //dp[j]表示组成j 所需最少硬币个数
    int coinChange(vector<int>& coins, int amount) {
         vector<int> dp(amount+1,INT_MAX);
         dp[0]=0;
         for(int i=0;i<coins.size();i++){
             for(int j=coins[i];j<=amount;j++){
                  if (dp[j - coins[i]] != INT_MAX)
                  dp[j] =min(dp[j],dp[j-coins[i]]+1);        
             }
         }
         if(dp.back()==INT_MAX)return -1;
         else
         return dp.back();
    }

第三题:

简介:

  本题和上一题十分相似,只不过我们在遍历时要注意完全平方数就是物品(可以无限件使用),凑个正整数n就是背包,问凑满这个背包最少有多少物品?这样本题是不是就很清晰了。

代码实现:

先遍历背包,再遍历物品

int numSquares(int n) {
        vector<int> dp(n + 1, INT_MAX);
        dp[0] = 0;
        for (int i = 0; i <= n; i++) { // 遍历背包
            for (int j = 1; j * j <= i; j++) { // 遍历物品
                dp[i] = min(dp[i - j * j] + 1, dp[i]);
            }
        }
        return dp[n];
    }

先遍历物品,再遍历背包

    int numSquares(int n) {
        if(n<4)return n;
        vector<int> dp(n+1,INT_MAX);
        dp[0] = 0;
        for(int i=1;i*i<=n;i++){
            for(int j=i*i;j<=n;j++){
               dp[j] =min(dp[j],dp[j-i*i]+1);
            }
        }
        return dp.back();
    }

总结:

今天使用感觉更加得心应手了,还需努力!

 

 


http://www.kler.cn/a/145909.html

相关文章:

  • Spring 中的事件驱动模型
  • Python----Python高级(文件操作open,os模块对于文件操作,shutil模块 )
  • 【面试题】JVM部分[2025/1/13 ~ 2025/1/19]
  • ChatGPT被曝存在爬虫漏洞,OpenAI未公开承认
  • GIFT ICA 下载记录
  • 2024又是一年的CSDN之旅-总结过去展望未来
  • 什么是工业物联网(IOT)?这样的IOT平台你需要吗?——青创智通
  • MySQL(免密登录)
  • 【STM32单片机】贪吃蛇游戏设计
  • 【算法】装备合成(二分)
  • 【UCAS自然语言处理作业二】训练FFN, RNN, Attention机制的语言模型,并计算测试集上的PPL
  • 电子学会C/C++编程等级考试2021年09月(三级)真题解析
  • redisserver一闪而过 redis闪退解决版本
  • 深信服超融合一体机提示:内存ECC
  • Echarts title标题配置项的使用 更改颜色 副标题
  • 常见树种(贵州省):021冬青、连香树、白辛树、香合欢、云贵鹅耳枥、肥牛树、杜英、格木、黄连木、圆果化香树、南天竹
  • 基于51单片机直流电机PWM控制设计
  • linux环境下对mysql操作
  • FilterChain攻击解析及利用
  • ATK-ESP8266 WIFI模块串口通信通用实现方案
  • mac VScode 添加PHP debug
  • 在 Ubuntu 上安装最新版的 Calibre
  • ElasticSearch之禁用交换分区
  • 数据结构 / 顺序表的遍历
  • 云匣子 FastJson反序列化RCE漏洞复现
  • 京东数据分析(京东大数据):2023年10月京东手机行业品牌销售排行榜