《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,一经查实,立即删除!

相关文章

《dp补卡——多重背包》

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

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补卡——子序列问题》

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

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

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

explain用法

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

转:Google论文之三----MapReduce

文章来自于&#xff1a;http://www.cnblogs.com/geekma/p/3139823.html MapReduce&#xff1a;大型集群上的简单数据处理 摘要 MapReduce是一个设计模型&#xff0c;也是一个处理和产生海量数据的一个相关实现。用户指定一个用于处理一个键值&#xff08;key-value&#xff09;…

《DBNotes:Join算法的前世今生》

目录NestLoopJoin算法Simple Nested-Loop JoinIndex Nested-Loop JoinBlock Nested-Loop JoinBatched Key AccessHash Join算法In-Memory Join(CHJ)On-Disk Hash Join参考链接在8.0.18之前&#xff0c;MySQL只支持NestLoopJoin算法&#xff0c;最简单的就是Simple NestLoop Joi…

UNITY3D与iOS交互解决方案

原地址&#xff1a;http://bbs.18183.com/thread-456979-1-1.html 本帖最后由 啊,将进酒 于 2014-2-27 11:17 编辑 “授人以鱼&#xff0c;不如授人以渔”&#xff0c;以UNITY3D调用iOS版的91SDK为例&#xff0c;利用C# / C / OBJ-C交互原理,本文将详细介绍UNITY3D与iOS之间交互…

AP in R

AP聚类算法是目前十分火的一种聚类算法&#xff0c;它解决了传统的聚类算法的很多问题。不仅简单&#xff0c;而且聚类效果还不错。这里&#xff0c;把前两天学习的AP算法在R语言上面的模拟&#xff0c;将个人笔记拿出来与大家分享一下&#xff0c;不谈AP算法的原理&#xff0c…

nginx 模块解析

nginx的模块非常之多&#xff0c;可以认为所有代码都是以模块的形式组织&#xff0c;这包括核心模块和功能模块&#xff0c;针对不同的应用场合&#xff0c;并非所有的功能模块都要被用到&#xff0c;附录A给出的是默认configure&#xff08;即简单的http服务器应用&#xff09…

《LeetcodeHot100非困难题补录》

最近比较闲&#xff0c;也比较焦虑&#xff0c;刷刷题吧 目录11. 盛最多水的容器22. 括号生成31. 下一个排列48. 旋转图像49. 字母异位词分组56. 合并区间75. 颜色分类79. 单词搜索114. 二叉树展开为链表141. 环形链表148. 排序链表152. 乘积最大子数组169. 多数元素207. 课程表…

《MySQL8.0.22:Lock(锁)知识总结以及源码分析》

目录1、关于锁的一些零碎知识&#xff0c;需要熟知事务加锁方式&#xff1a;Innodb事务隔离MVCC多版本并发控制常用语句 与 锁的关系意向锁行级锁2、锁的内存结构以及一些解释3、InnoDB的锁代码实现锁系统结构lock_sys_tlock_t 、lock_rec_t 、lock_table_tbitmap锁的基本模式的…

《Linux杂记:一》

目录CPU负载和CPU利用率CPU负载很高,利用率却很低的情况负载很低,利用率却很高常用linux命令常用的文件、目录命令常用的权限命令常用的压缩命令CPU负载和CPU利用率 可以通过 uptime , w 或者 top 命令看到CPU的平均负载。 Load Average :负载的3个数字,比如上图的0.57、0.4…

Iptables入门教程

转自&#xff1a;http://drops.wooyun.org/tips/1424 linux的包过滤功能&#xff0c;即linux防火墙&#xff0c;它由netfilter 和 iptables 两个组件组成。 netfilter 组件也称为内核空间&#xff0c;是内核的一部分&#xff0c;由一些信息包过滤表组成&#xff0c;这些表包含内…

No identities are available for signing 的解决办法

今天重新上传做好的app提交到app store&#xff0c;结果就出现标题上的错误。“No identities are available for signing”。 以后碰到这样的问题按照下面几个步骤来做&#xff1a; 进入Distribution -----下载发布证书 -----双击安装-----重启Xcode就能上传了 其他细节 如果再…

匿名方法和Lambda表达式

出于MVVM学习的需要&#xff0c;复习下匿名方法和Lambda表达式&#xff0c;因为之前用的也比较少&#xff0c;所以用的也不是很熟练&#xff0c;Baidu下相关的知识&#xff0c;写了这个Demo&#xff0c;目标是用简单的方法展示这个怎么用。 这里偏重的和LINQ中的Lambda表达式 …

烂橘子

Problem Statement: 问题陈述&#xff1a; Given a matrix of dimension r*c where each cell in the matrix can have values 0, 1 or 2 which has the following meaning: 给定尺寸r * C的矩阵&#xff0c;其中矩阵中的每个单元可以具有其具有以下含义的值0&#xff0c;1或2…

别人的算法学习之路

http://www.cnblogs.com/figure9/p/3708351.html 我的算法学习之路 关于 严格来说&#xff0c;本文题目应该是我的数据结构和算法学习之路&#xff0c;但这个写法实在太绕口——况且CS中的算法往往暗指数据结构和算法&#xff08;例如算法导论指的实际上是数据结构和算法导论&a…

git config命令使用第二篇——section操作,多个key值操作,使用正则

接上一篇&#xff0c;git config命令使用第一篇——介绍&#xff0c;基本操作&#xff0c;增删改查:http://blog.csdn.net/hutaoer06051/article/details/8275069 1. 删除一个section 命令参数 --remove-section 格式&#xff1a;git config [--local|--global|--system] --rem…