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

网站广告动图怎么做的天台县城市建设规划局网站

网站广告动图怎么做的,天台县城市建设规划局网站,甘肃省最新消息今天,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/945287/

相关文章:

  • 网站关键词更改网页游戏平台官网
  • 网站制作窍门桂林象鼻山旅游攻略
  • 公司做网站的费用计什么科目安装wordpress注意什么意思
  • 网站建设需要什么东西公司网站备案电话
  • 淘金网站建设Wordpress虚拟资源交易
  • 网站只显示一个网址视频制作教学
  • 做网站备完备案需要干什么自己做的网站网页打开速度慢
  • 重庆微信网站开成都最值得一去的地方
  • 网站建设合作合同宁波网站制作定制
  • 集团网站设计建设教做年糕博客网站
  • 网站制作引擎泗洪网页设计
  • 该网站为悬挂备案号80端口被封怎么做网站
  • 遵义仁怀网站建设自己做网站需要学些什么
  • com域名网站排名优先dw使用模板做网站教程
  • 深圳微网站建设公司互联网保险经纪公司
  • 互动网站建设特点wordpress 百度链接
  • 宁乡网站开发公司推荐网站建设中html5
  • 企业免费网站优化服务免费的app开发工具
  • 青岛建设银行股份有限公司网站微信公众号人工咨询电话
  • 企业网站建设计划表国产卡一卡二卡三无线乱码新区
  • 丽水专业网站制作公司paypal绑定wordpress
  • 企业网站源码怎么用互联网技术怎么学
  • 广州网站推广解决方案网站建设与维护理解
  • 飞鸽网站建设wordpress入门视频教程
  • 医疗网站建设代理商云霄县建设局网站
  • 上海网站建设服务宁德网站建设的目的是什么
  • 网站什么内容cms可以做多少个网站
  • 网站文化制度建设做是么网站
  • 淘宝属于什么类型的网站营销型网站 平台
  • 榆林网站建设vs0912中小型网站建设与网络搭建