E10 背包DP 多重背包 二进制优化
E10 背包DP 多重背包 二进制优化——信息学奥赛算法_哔哩哔哩_bilibili
// 朴素 TLE #include<bits/stdc++.h> using namespace std; int n,m; int f[1005][20005]; int main(){ scanf("%d%d",&n,&m); for(int i=1,v,w,s; i<=n; i++){ //物品 scanf("%d%d%d",&v,&w,&s); for(int j=0; j<=m; j++){ //体积 for(int k=0; k<=s&&k*v<=j; k++) //个数 f[i][j]=max(f[i][j],f[i-1][j-k*v]+k*w); } } printf("%d\n",f[n][m]); }
// 优化空间 TLE #include<bits/stdc++.h> using namespace std; int n,m; int f[20005]; int main(){ scanf("%d%d",&n,&m); for(int i=1,v,w,s; i<=n; i++){ //物品 scanf("%d%d%d",&v,&w,&s); for(int j=m; j>=v; j--){ //体积 for(int k=0; k<=s&&k*v<=j; k++) //个数 f[j]=max(f[j],f[j-k*v]+k*w); } } printf("%d\n",f[m]); }
// 二进制拆分个数优化,转化为01背包 #include<bits/stdc++.h> using namespace std; int n,m,num; int v[16000],w[16000]; //20000<2^16 int f[20005]; int main(){ cin>>n>>m; for(int i=1,v1,w1,s; i<=n; i++){ cin>>v1>>w1>>s; for(int j=1; j<=s; j<<=1){ v[++num]=j*v1; w[num]=j*w1; s-=j; } if(s) v[++num]=s*v1,w[num]=s*w1; } for(int i=1; i<=num; i++) for(int j=m; j>=v[i]; j--) f[j]=max(f[j],f[j-v[i]]+w[i]); cout<<f[m]; }
// 二进制拆分个数优化,转化为01背包 #include<iostream> using namespace std; int n,m,num; int v[100005],w[100005]; int f[40005]; int main(){ cin>>n>>m; for(int i=1,v1,w1,s; i<=n; i++){ cin>>w1>>v1>>s; //价值 重量 个数 for(int j=1; j<=s; j<<=1){ //j=1,2,4... v[++num]=j*v1; w[num]=j*w1; s-=j; } if(s) v[++num]=s*v1,w[num]=s*w1; } for(int i=1; i<=num; i++) for(int j=m; j>=v[i]; j--) f[j]=max(f[j],f[j-v[i]]+w[i]); cout<<f[m]; }
浙公网安备 33010602011771号