A607题解
2026-08-14 17:24:20
发布于:浙江
26阅读
0回复
0点赞
背景:
原题链接
背包动态规划模板题,但又要点优化。
思路:
多重背包模板题,但由于数据范围,如果将每个物品都拆分成01背包,那么最多有个物品,最多,再按01背包最坏时间复杂度为,1s内根本运行不完,所以要用倍增法优化。(详细讲解——OI Wiki)
将数量每个拆分为各不相同的的整数次幂,要是有剩下的就用剩下的。如数量拆分为,拆分为,再将这些数乘以相应的重量和价值,成为01背包的一个物品,这样时间复杂度就能降为,1s内完全可以运行完。最后写一遍01背包模板即可。
代码:
#include <iostream>
using namespace std;
int w[1010],v[1010];
int dp[1010];
int main(){
int m,n;
cin>>m>>n;
int cnt=0;//这里cnt为01背包的物品数量,里面的数量为z
for (int i=1;i<=n;i++){
int x,y,z;//局部变量,x为重量,y为价值,z为数量
cin>>x>>y>>z;
for (int j=1;j<=z;j*=2){//2的整数次幂
w[++cnt]=j*x;
v[cnt]=j*y;//2的次幂乘以相应的重量、价值
z-=j;//减去2的整数次幂
}
if (z){
w[++cnt]=z*x;
v[cnt]=z*y;
}//如果数量减去不重复的2的整数次幂还有剩余,也加到01背包中
}
for (int i=1;i<=cnt;i++){
for (int j=m;j>=w[i];j--){
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}//01背包模板
cout<<dp[m];//dp[i]为总质量最多为i时,背包能装的最大价值
return 0;
}
结语:
希望对大家学习OI有帮助!
这里空空如也








有帮助,赞一个