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

自动识别手机和电脑版本网站百度网站收录更新

自动识别手机和电脑版本网站,百度网站收录更新,少儿编程python课程,wordpress比较火的主题题目来源:https://leetcode.cn/problems/partition-equal-subset-sum/description/ C题解(思路来源代码随想录) : 背包问题有多种背包方式,常见的有:01背包、完全背包、多重背包、分组背包和混合背包等等。…

题目来源:https://leetcode.cn/problems/partition-equal-subset-sum/description/

C++题解(思路来源代码随想录) :

背包问题有多种背包方式,常见的有:01背包、完全背包、多重背包、分组背包和混合背包等等。一个商品如果可以重复多次放入是完全背包,而只能放入一次是01背包,本题中是01背包。

把01背包问题套到本题上来。

  • 背包的体积为sum / 2
  • 背包要放入的商品(集合里的元素)重量为元素的数值,价值也为元素的数值
  • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  • 背包中每一个元素是不可重复放入。

以上分析完,我们就可以套用01背包,来解决这个问题了。

  1. 确定dp数组以及下标的含义。二维数组: dp[i][j]表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
  2. 确定递推公式。两种情况:不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。);放物品i:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值。所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
  3. dp数组初始化。一定要和dp数组的定义吻合,否则到递推公式的时候就会越来越乱。首先从dp[i][j]的定义出发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。状态转移方程可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化,即i为0,存放编号0的物品的时候,各个容量的背包所能存放的最大价值。当 j < weight[0]的时候,dp[0][j] 应该是 0;当j >= weight[0]时,dp[0][j] 应该是value[0]。
  4. 确定遍历顺序。有两个遍历的维度:物品与背包重量。都可以! 但是先遍历物品更好理解
  5. 举例推导dp数组。
class Solution {
public:bool canPartition(vector<int>& nums) {int len = nums.size();int sum = 0;for(int i = 0; i < len; i++) {sum += nums[i];}if(sum % 2 == 1) return false;vector<vector<int>> dp(len, vector<int>(sum/2+1, 0));for(int ii = nums[0]; ii <= sum/2; ii++) {dp[0][ii] = nums[0];}// 相当于包容量为sum/2,在len个物品中挑选,能装满则返回true。// 表示从0-j的元素中,取出和小于k的最大值。for(int j = 1; j < len; j++) {for(int k = 0; k <= sum/2; k++) {if(k < nums[j]) dp[j][k] = dp[j-1][k];else dp[j][k] = max(dp[j-1][k], dp[j-1][k-nums[j]]+nums[j]);}}if(dp[len-1][sum/2] == sum/2) return true;else return false;}
};

# 使用一维dp数组(滚动数组)

在使用二维数组的时候,递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);

其实可以发现如果把dp[i - 1]那一层拷贝到dp[i]上,表达式完全可以是:dp[i][j] = max(dp[i][j], dp[i][j - weight[i]] + value[i]);

与其把dp[i - 1]这一层拷贝到dp[i]上,不如只用一个一维数组了,只用dp[j](一维数组,也可以理解是一个滚动数组)。这就是滚动数组的由来,需要满足的条件是上一层可以重复利用,直接拷贝到当前层。

在一维dp数组中,dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。

注意:遍历顺序必须先遍历物品再遍历包容量,且更新内层for循环需要递减(从后往前),因为滚动数组的更新需要用到未更新的前面元素,如果是递增(从前往后),前面更新的元素会影响后面的元素。

class Solution {
public:bool canPartition(vector<int>& nums) {int sum = 0;// dp[i]中的i表示背包内总和// 题目中说:每个数组中的元素不会超过 100,数组的大小不会超过 200// 总和不会大于20000,背包最大只需要其中一半,所以10001大小就可以了vector<int> dp(10001, 0);for (int i = 0; i < nums.size(); i++) {sum += nums[i];}// 也可以使用库函数一步求和// int sum = accumulate(nums.begin(), nums.end(), 0);if (sum % 2 == 1) return false;int target = sum / 2;// 开始 01背包for(int i = 0; i < nums.size(); i++) {for(int j = target; j >= nums[i]; j--) { // 每一个元素一定是不可重复放入,所以从大到小遍历dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);}}// 集合中的元素正好可以凑成总和targetif (dp[target] == target) return true;return false;}
};

http://www.yayakq.cn/news/41045/

相关文章:

  • 温州市住房和城乡建设厅网站河北大名网站建设招聘
  • 大连企业制作网站网页设计实验报告实验1
  • 做网站要准备什么资料泉州网站建设服务
  • 网站建设费 什么科目qqip.探测网站建设
  • ui设计的推荐网站及网址wordpress镶入thinkphp
  • 四川手机网站设计做家居网站设计
  • 空包网网站怎么做的惠州做网站
  • 网站服务器有哪些零基础wordpress
  • 学科主题资源网站的建设网页设计代码td th
  • 个人flash网站源码做网站能赚多少钱
  • 网站开发yuanmus网络营销推广seo
  • 婚庆网站开发计划书node.js网站开发
  • 厦门高端网站建设公做个网站费用
  • 网站建设流程图visio高端网站建设浩森宇特
  • 建立网站时服务器的基本配置有哪些惠州网站建设效果
  • 有人在相亲网站骗人做传销女神异闻录3剧场版
  • 建设部网站黑臭水体公布dede网站备份
  • 网站手机微信三合一怎么做双流网站建设
  • 网站建设与推广综合实训报告册中国住房和城乡建设厅网站首页
  • 昆明定制化网站建设如何做网站免费
  • 网站开发代码语言拼多多关键词排名在哪里看
  • 大型网站架设需要考虑哪些问题flash asp网站
  • 免备案的网站网络设计
  • 广东深圳电子厂网站seo优化软件
  • 流行网站开发框架中国移动idc建设网站
  • 在哪做网站关键词2013年建设工程发布网站
  • 石家庄新钥匙网站网页设计美工培训班
  • 东莞横沥网站制作嘉兴模板建站定制
  • 做视频网站需要什么空间吗为什么做的网站有的有弹窗有的没有
  • 运河网站制作中国专利申请网官网