佛山营销网站旅游网站建设方案后台
news/
2025/10/3 17:27:20/
文章来源:
佛山营销网站,旅游网站建设方案后台,wordpress 改密码,网站开发项目可行性分析0-1背包理论基础
基础
DP数组与其下标的含义
dp[i][j]#xff0c;i为物品编号#xff0c;j为背包容量
dp[i][j]表示从下标为[0-i]的物品里任意取#xff0c;放进容量为j的背包#xff0c;价值总和最大是多少。
递推公式
分类#xff1a;是否要放入下标为i的物品i为物品编号j为背包容量
dp[i][j]表示从下标为[0-i]的物品里任意取放进容量为j的背包价值总和最大是多少。
递推公式
分类是否要放入下标为i的物品
· 不放时最大价值为dp[i - 1][j]
· 放入时最大价值为dp[i - 1][j – weight[i]] value[i]
递推取两者较大值dp[i][j] max(dp[i - 1][j], dp[i - 1][j – weight[i]] value[i])
DP数组初始化
dp[i][j]由其上方格子和左上方范围内某一个格子初始化而来所以需要初始化最上的一行和最左的一列 i 0时对于j weight[0]的格子初始化为0往后的格子初始化为value[0] j 0时背包容量为0装不下任何物品所以最左列全部初始化为0
遍历顺序
先遍历物品i或先遍历背包j都可以都能将dp数组填满
滚动数组优化
因为dp[i][j]的值只由i-1行元素推出所以dp数组可以使用一维滚动数组来代替二维数组
注意使用滚动数组时不能先遍历背包只能先遍历物品。遍历物品时遍历背包的顺序应该从右到左思考一下覆盖的顺序 416.分割等和子集
这题其实没有提示挺难想到背包解法的告诉我是背包题也想了半天
这题用背包解得想明白 j 是什么寻找两个总和相等的子集等价于寻找一个和为所以数总和一半的子集所以 j 是数的总和而 j 的最大值应该是数组中所有数总和的一半 1、DP数组定义一维数组使用滚动数组来实现背包。方便理解使用二维数组来解释定义dp[i][j]表示 n i 时数组下标[0, i]中取任意数所能得到的最大值这个最大值不能超过j · weight[i] 和 value[i] 都等于 nums[i] · value[i] nums[i] 使在遍历物品时不断取到最大值 · weight[i] nums[i] 使在遍历背包时最大值不超过总和的一半 · 最后遍历完了所有物品和背包后如果dp[-1][-1] 总和的一半说明能恰好取到一个子集其总和为所有数总和的一半 2、DP数组初始化i nums[0]的格子初始化为0往后的格子初始化为value[0] 3、递推公式常规0-1背包问题的递推公式滚动数组实现 dp[j] max(dp[j], dp[j - nums[i]] nums[i]); bool canPartition(vectorint nums) {int sum 0;for (int n : nums)sum n;if (sum % 2 1)return false;// weight[i]与value[i]都设置为nums[i]// 当背包大小为sum / 2时看最大数总和是否也是sum / 2sum / 2;vectorint dp(sum 1, 0);for (int j 0; j sum 1; j)if (j nums[0]) dp[j] nums[0];for (int i 1; i nums.size(); i) {for (int j sum; j nums[i]; --j) {dp[j] std::max(dp[j], dp[j - nums[i]] nums[i]);}}return dp[sum] sum;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/926129.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!