《dp补卡——完全背包问题》

在这里插入图片描述
N件物品和一个最多能背重量为W的背包。第i件物品的重量为weight[i],得到的价值是value[i]。每件物品都有无限个(可以放入背包多次),求解将哪些物品装入背包里物品价值总和最大。
01背包和完全背包唯一不同在于遍历顺序上。

01背包的核心代码:

for(int i = 0; i < weight.size(); i++)	//遍历物品
{for(int j = bagWeight; j >= weight[i]; j--)	//遍历背包容量{dp[j] = max(dp[j],dp[j-weight[i]]+value[i]);}
}

内嵌的循环是从大到小遍历,为了保证每个物品仅仅被添加一次。而完全背包的物品是可以添加多次的,所以要从小到大去遍历。

for(int i = 0; i < weight.size(); i++)	//遍历物品
{for(int j = weight[i]; j <= bagWeight; j++)	//遍历背包容量{dp[j] = max(dp[j],dp[j-weight[i]]+value[i]);}
}

leetcode题目

        • [518. 零钱兑换 II](https://leetcode-cn.com/problems/coin-change-2/)
        • [377. 组合总和 Ⅳ](https://leetcode-cn.com/problems/combination-sum-iv/)
        • 爬楼梯变形
        • [322. 零钱兑换](https://leetcode-cn.com/problems/coin-change/)
        • [279. 完全平方数](https://leetcode-cn.com/problems/perfect-squares/)
        • [139. 单词拆分](https://leetcode-cn.com/problems/word-break/)

518. 零钱兑换 II

这一题与https://blog.csdn.net/qq_42604176/article/details/116051902?spm=1001.2014.3001.550101背包中的组合问题有相似之处。只需要把遍历顺序修改就行了。
step1: dp[j]:凑成总金额j的货币组合数为dp[j]
step2: dp[j] += dp[j - coins[i]];
step3: 凑成总金额0的货币组合数为1。
step4:使用完全背包的遍历方式,注意由于是求组合数,内外嵌套需要注意。

AC代码如下:

class Solution {
public:int change(int amount, vector<int>& coins) {int sum = 0;vector<int> dp(amount+1,0);dp[0]=1;for(int i = 0; i < coins.size(); i++){for(int j = coins[i]; j <= amount; j++){dp[j] += dp[j-coins[i]];}}return dp[amount];}
};

代码随想录公众号做出的这个总结很好,虽然现在还没有完全理解是为什么:
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。

377. 组合总和 Ⅳ

如果本题要把排列都列出来的话,只能使用回溯算法爆搜。
但是它只要求我们得到排列方法的数目。由于可以重复取,所以使用完全背包。由于是求排列数,外层for循环遍历背包,内层for循环遍历元素。
最内层需要对两个数相加小于INT_MAX进行限制。

class Solution {
public:int combinationSum4(vector<int>& nums, int target) {vector<int> dp(target+1,0);dp[0] = 1;for(int i = 0; i <= target; i++)    //遍历背包容量{for(int j = 0; j < nums.size(); j++)    //遍历物品{if(i >= nums[j] && dp[i] < INT_MAX -  dp[i-nums[j]])dp[i] += dp[i-nums[j]];  }}return dp[target];}
};

爬楼梯变形

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次可以爬 1 、 2或者m 个台阶。问有多少种不同的方法可以爬到楼顶呢?
分析:1阶,2阶,m阶就是物品,楼顶就是背包。每一阶可以重复使用,例如跳了1阶,还可以继续跳1阶。所以这是一个完全背包问题。
step1 : dp[i]爬到有i个台阶的楼顶,有dp[i]种方法。

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

step3: dp[0] = 1,dp[…]=0;

step4:遍历顺序,由于是排列问题,1、2与2、1是不一样的,所以将背包容量放在外层循环,将物品放到内层循环。又因为是完全背包问题,所以从前向后遍历。

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

322. 零钱兑换

step1:dp[j]凑足金额为j所需要的钱币的最少个数为dp[j]
step2:dp[j] = min(dp[j-coins[i]]+1,dp[j]);
step3:凑足金额为0的所需金币个数为0,即dp[0]=0;其他初值为INT_MAX。
凑足金额为j-coins[i]的最少个数为dp[j-coins[i]],那么只需要加上一个钱币coins[i]即dp[j-coins[i]]+1就是dp[j].
step4:求最小个数,钱币有顺序无顺序都可以,都不影响钱币的最小个数。
求组合数,for外层遍历物体,for内层遍历背包。求排列,外层for遍历背包,内层for循环遍历物品。
本题两者均可。

class Solution {
public: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) continue;dp[j] = min(dp[j-coins[i]]+1,dp[j]);}}//如果没有被赋值,那么说明没有解,返回-1if(dp[amount] == INT_MAX) return -1;return dp[amount];}
};

279. 完全平方数

完全平方数就是物品(无限使用),凑成的正整数n就是背包。问凑满背包最少有多少个物品。
step1:dp[j],凑满容量为j的背包最少物品数目。
step2:dp[j] = min(dp[j-i*i] +1,dp[j]);
step3: dp[0] = 0;虽然0符合完全平方数要求,但是题目要求是从1开始找完全平方数。其余下标的dp初始值为INT_MAX
step4:对于求最小方法数的,内外层不需要管循环。

class Solution {
public:int numSquares(int n) {vector<int> dp(n+1,INT_MAX);dp[0] = 0;for(int i = 1; i <= n; i++){for(int j = i*i; j <= n; j++){if(dp[j-i*i] == INT_MAX) continue;dp[j] = min(dp[j-i*i]+1,dp[j]);}}return dp[n];}
};

139. 单词拆分

物品:wordDict中的string,可以重复取
背包:s字符串
step1: dp[i]:字符串长度为i,dp[i]为true,表示可以拆分一个或者多个在字典中出现的单词。
step2: 如果dp[j]为true,则[j,i]这个区间的子串出现在字典里,那么dp[i]一定为true。
所以递推公式为;

if(wordSet.find(s.substr(j,i-j)) != wordSet.end() && dp[j]) dp[i] = true;

step3:dp[0]字符串为0,为了方便推导公式,我们只好给他true,不然公式推导下去全为false。
step4:由于是求最小方法数,所以内外层遍历顺序无需在意

class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {//将vector放入set中,加快查询unordered_set<string> wordSet(wordDict.begin(),wordDict.end());vector<bool> dp(s.size()+1,false);dp[0] = true;for(int i = 0; i <= s.size(); i++)  //背包容量{for(int j = 0; j <= i; j++)           //物品{string str = s.substr(j,i-j);  if(wordSet.find(str) != wordSet.end() && dp[j] == true){dp[i] = true;}}}return dp[s.size()];}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377101.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中的类型转换

类型转换 (Typecasting) Typecasting is a term which is introduced in all the language similar to java. Typecasting是一个用与Java类似的所有语言引入的术语。 When we assign primitive datatype to another datatype. 当我们将原始数据类型分配给另一个数据类型时。 I…

让crash文件中的内存地址变成函数名称,

假如程序员编译了inhouse给测试。 如果在测试过程中出现奔溃现象&#xff0c;我想程序员一般会来看Device Log 也就是 crash文件 如果crash文件遇到如下的情况&#xff0c;在重要的地方看不到函数名称。我想是一件很奔溃的事情。 1 Exception Type: EXC_BAD_ACCESS (SIGSEGV)2…

《dp补卡——多重背包》

多重背包简介&#xff1a; 有N种物品和一个容量为V的背包。第i种物品最多有Mi件可用&#xff0c;每件耗费的空间为Ci&#xff0c;价值为Wi。求解将哪些物品装入背包可使得这些物品耗费的空间总和不超过背包容量&#xff0c;且价值总和最大。 将Mi件摊开&#xff0c;就是一个01背…

kafka消息确认ack_什么是确认(ACK)? ACK代表什么?

kafka消息确认ackACK&#xff1a;致谢 (ACK: Acknowledgment) An acknowledgment (ACK) is a signal that is passed among the communicating processes, computers, or devices to indicate acknowledgment, or delivery of the message, as a component of a communications…

CocoaAsyncSocket 套接字

CocoaAsyncSocket 套接字 https://github.com/robbiehanson/CocoaAsyncSocket Asynchronous socket networking library for Mac and iOS 用于iOS以及Mac的异步套接字网络库。 TCP GCDAsyncSocket and AsyncSocket are TCP/IP socket networking libraries. Here are the key…

谷歌浏览器设置缓存方法

谷歌浏览器设置缓存方法&#xff1a; 1、在桌面Google Chrome快捷方式&#xff0c;目标&#xff1a;找到 C:\Users\Splendid\AppData\Local\…\Application\chrome.exe 在这后面加上-Disk-Cache-Dir”Z:\TEMP” 注意: -Disk前面有空格&#xff0c;”Z:\TEMP” 是文件存放在Z盘T…

《dp补卡——买卖股票问题》

目录121. 买卖股票的最佳时机贪心dp思路滚动数组优化122. 买卖股票的最佳时机 II123. 买卖股票的最佳时机 III188. 买卖股票的最佳时机 IV309. 最佳买卖股票时机含冷冻期714. 买卖股票的最佳时机含手续费121. 买卖股票的最佳时机 贪心 取最左最小值&#xff0c;取最右最大值&…

oo0ooo0ooo0oo_OoO的完整形式是什么?

oo0ooo0ooo0ooOoO&#xff1a;外出 (OoO: Out of Office) OoO is an abbreviation of "Out of Office". OoO是“不在办公室”的缩写。 It is an expression, which is commonly used in the Gmail platform. It is written in the body or the subject of the email…

SP2010开发和VS2010专家食谱--第三章节--高级工作流(2)--为沙盒解决方案创建自定义活动...

尽管沙河解决方案功能有限&#xff0c;你仍然可以开发自定义活动&#xff0c;在SharePoint Designer中使用而不用改变web.config或添加.ACTION文件到根文件夹。 转载于:https://www.cnblogs.com/crazygolf/p/3856795.html

sql where 1=1和 0=1 的作用

where 11; 这个条件始终为True&#xff0c;在不定数量查询条件情况下&#xff0c;11可以很方便的规范语句。 一、不用where 11 在多条件查询中的困扰 举个例子&#xff0c;如果您做查询页面&#xff0c;并且&#xff0c;可查询的选项有多个&#xff0c;同时&#xff0c;还让用户…

j@2ff4f00f_J4F的完整形式是什么?

j2ff4f00fJ4F&#xff1a;只是为了好玩 (J4F: Just For Fun) J4F is an abbreviation of "Just For Fun". J4F是“ Just For Fun”的缩写 。 It is an expression, which is commonly used in messaging or chatting on social media networking sites like Faceboo…

《dp补卡——子序列问题》

目录300. 最长递增子序列674. 最长连续递增序列718. 最长重复子数组1143. 最长公共子序列53. 最大子序和392. 判断子序列115. 不同的子序列583. 两个字符串的删除操作72. 编辑距离647. 回文子串 &#xff08;与 5.最长回文子串思路差不多&#xff09;516. 最长回文子序列300. 最…

[LeetCode] Maximal Rectangle

Given a 2D binary matrix filled with 0s and 1s, find the largest rectangle containing all ones and return its area. 在做 Largest Rectangle in Histogram的时候有人说可以用在这题&#xff0c;看了一下还真是&#xff0c;以每行为x轴&#xff0c;每列往上累计的连续的…

什么是alpha测试_什么是ALPHA?

什么是alpha测试Α (ALPHA) Alpha is the first and foremost letter of the Greek alphabet. In the classification of Greek numerals or numbers, it constitutes a value of 1. Alpha是希腊字母的第一个也是最重要的字母 。 在希腊数字或希腊数字的分类中&#xff0c;它的…

《leetcode : 647. 回文子串 思考分析双指针解法》

647. 回文子串 如何确定是回文串&#xff1a; 找中心然后往两边扩散&#xff0c;判断是否对称即可。 在遍历中心点的时候&#xff0c;注意中心点可以是一个元素也可以是两个元素。 class Solution { public:int cal_two_extend(const string& s,int i,int j,int n){int re…

天草初级班(3)

算术运算指令算术运算指令是反映CPU计算能力的一组指令&#xff0c;也是编程时经常使用的一组指令。它包括&#xff1a;加、减、乘、除及其相关的辅助指令。 该组指令的操作数可以是8位、16位和32位(80386)。当存储单元是该类指令的操作数时&#xff0c;该操作数的寻址方式可以…

4.3.3版本之引擎bug

bug描述&#xff1a;   IOS设备上&#xff0c;当使用WWW www WWW.LoadFromCacheOrDownload(url, verNum); 下载资源时&#xff0c;第一次下载某个资源&#xff0c;www.assetBundle必定为空。 解决办法&#xff1a;   引擎版本降到4.3.2或者升到4.3.4或更高。 这个bug绝对是…

sml完整形式_411的完整形式是什么?

sml完整形式411&#xff1a;信息 (411: Information) 411 is an abbreviation of “Information". 411是“信息”的缩写 。 It is an expression, which is commonly used in messaging or chatting on social media networking sites like Facebook, Yahoo Messenger, a…

php 检测用户是否关闭浏览器

1、例子1 echo str_repeat(" ",3000);ignore_user_abort(true); mylog(online);while (true) {/** 1、程序正常结束 connection_status 0* 2、点击浏览器“停止”按钮 connection_status 1* 3、超时 connection_status 2*/echo "test<br>\n&qu…

explain用法

explain用法 EXPLAIN SELECT …… 变体&#xff1a; 1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句&#xff0c;运行SHOW WARNINGS 可得到被MySQL优化器优化后的查询语句 2. EXPLAIN PARTITIONS SELECT …… 用于分区表的EXPLAIN 执行计划包含的信息 id…