LeetCode动态规划(九):完全背包(初级)
创始人
2024-05-22 09:24:14
0

学习目标:

理解完全背包和0-1背包遍历顺序的区别


学习内容:

15. LeetCode377. 组合总和 Ⅳicon-default.png?t=N0U7https://leetcode.cn/problems/combination-sum-iv/

16. 爬楼梯(进阶班版)

17. LeetCode322. 零钱兑换icon-default.png?t=N0U7https://leetcode.cn/problems/coin-change/

18. LeetCode279. 完全平方数icon-default.png?t=N0U7https://leetcode.cn/problems/perfect-squares/


学习产出:

独立解决以上题目

15. LeetCode377. 组合总和 Ⅳ

 

思路:本题和零钱兑换II是同一类型的题,换汤不换药
注意:顺序不同的序列视作不同的组合,因此是求排列数(元素是有序的)而不是组合数1.dp[i]:组成i的排列个数
2.dp[i]+=dp[i-nums[j]]:只要能够获取到nums[j],dp[i-nums[j]]是dp[i]的一部分
3.初始化dp:dp[0]=1,这样递推其他数值时才有基础,其他数值初始化为0,这样才不会影响累加值
4.遍历顺序:本质上就是对于每个容量i,用nums里所有元素去组合,从最基础的开始。比如说1个1组成1,2个1组成2,1个2组成2……4.1组合数:外层物品,内层容量4.2排列数:外层容量,内层物品(因为物品有顺序,顺序不同组合不同,所以我们在计算每个容量的方法数时,要把每个元素每种顺序都考虑到)4.3 eg.如果是外层遍历物品内层遍历容量,在计算dp[4]时,就会出现只有组合{1,3}而没有{3,1},因为3只会出现在1后面
class Solution {
public:int combinationSum4(vector& nums, int target) {//dp[i]:组成i的排列个数vectordp(target+1);//初始化dpdp[0]=1;//完善dpfor(int i=0;i<=target;i++){for(int j=0;j=0&&dp[i]<=INT_MAX-dp[i-nums[j]]){//在组成i-nums[j]的基础上,用nums[j]填补,从而累加相应的方法数//在组成dp[4]时://用1填补dp[3]:{1}+{1,2},{1}+{2,1},{1}+{1,1,1},{1}+{3}//用2填补dp[2]:{2}+{1,1},{2}+{2}//用3填补dp[1]:{3}+{1}//不用去管dp[1],dp[2],dp[3]是怎么组成的,但是可以确定1可以出现在3后面了//组成不同的i时,我们只遍历了一次nums里的所有元素,因此不会有重复排列出现dp[i]+=dp[i-nums[j]];}}}return dp[target];}
};

16. 爬楼梯(进阶班版)

改为:一步1个台阶、2个台阶、3个台阶、4个台阶……直到m个台阶(每一阶可以重复使用),求到达楼顶的总方法数。
理解:台阶就是物品,楼顶就是背包,本题被改编成了完全背包问题
1.dp[i]:爬到第i个台阶的方法数
2.dp[i]+=dp[i-j]:加入当前要走j个台阶,那么dp[i-j]就是dp[i]的一部分(从dp[i-1]累加到dp[i-j]),因为一步可以跨1~j个台阶
3.初始化dp:dp[0]是基础数值,由其推得其他dp值,所以dp[0]=1
4.遍历顺序:外背包,内物品。比如{1,2,1}和{1,1,2}实际上是不同的方法,其实就是求排列个数
int climbStairs(int m,int n){//dp[i]:爬到第i个台阶的方法数vectordp(n+1);//初始化dpdp[0]=1;//完善dpfor(int i=0;i<=n;i++){for(int j=1;j<=i;j++){//从1个台阶开始累加dp[i]+=dp[i-j];}}return dp[n];
}

17. LeetCode322. 零钱兑换

思路:
1.dp[j]:组成j的最少硬币数
2.dp[j]=min(dp[j],dp[j-coins[i]]+1):组成j-coins[i]最少的硬币数+coins[i]这枚硬币
3.初始化dp:dp[0]=0
4.遍历顺序:外物品内背包,外背包内物品都可以。本题只是求硬币个数,所以无论硬币面额有序还是无序都不影响。外物品内背包:
class Solution {
public:int coinChange(vector& coins, int amount) {//dp[j]:组成j的最少硬币数vectordp(amount+1,INT_MAX-1);//不影响最小值判断//初始化dpdp[0]=0;//完善dpfor(int i=0;i& coins, int amount) {vectordp(amount+1,INT_MAX-1);dp[0]=0;for(int i=0;i<=amount;i++){for(int j=0;j=0)dp[i]=min(dp[i],dp[i-coins[j]]+1);}}return dp[amount]==INT_MAX-1?-1:dp[amount];}
};

18. LeetCode279. 完全平方数

思路:
1.dp[i]:和为i的完全平方数的最少数量
2.dp[i]=min(dp[i],dp[i-j*j]+1)
3.初始化dp:vectordp(n+1,INT_MAX-1),dp[0]=0
4.遍历顺序:由于是求个数,所以无论哪种顺序都可以
class Solution {
public:int numSquares(int n) {//dp[i]:和为i的完全平方数的最少数量vectordp(n+1,INT_MAX-1);//初始化dpdp[0]=0;//完善dpfor(int i=1;i<=n;i++){for(int j=1;j*j<=i;j++){dp[i]=min(dp[i],dp[i-j*j]+1);}}return dp[n]==INT_MAX?-1:dp[n];}
};
j^2不是j的平方,而是j异或2

总结:题目要我们返回什么结果,动态规划表就表达什么意思。注意遍历顺序:如果是求组合数,就外物品内背包;如果是求组合数,就外背包内物品。

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...