① 01背包
有n件物品和一个容量为v的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。
#include<bits/stdc++.h> using namespace std; int main() { int t,n,v,i,j,w[1005],c[1005],dp[1005]; cin>>t; while(t--) { memset(dp,0,sizeof dp); cin>>n>>v; for(i=1;i<=n;i++) scanf("%d",&c[i]); for(i=1;i<=n;i++) scanf("%d",&w[i]);
for(i=1;i<=n;i++) for(j=v;j>=w[i];j--) dp[j]=max(dp[j],dp[j-w[i]]+c[i]); cout<<dp[v]<<endl; } return 0; }
② 完全背包
有n种物品和一个容量为v的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
#include<bits/stdc++.h> using namespace std; int main() { int t,n,v,i,j,w[1005],c[1005],dp[1005]; cin>>t; while(t--) { memset(dp,0,sizeof dp); cin>>n>>v; for(i=1;i<=n;i++) scanf("%d",&c[i]); for(i=1;i<=n;i++) scanf("%d",&w[i]); for(i=1;i<=n;i++) for(j=w[i];j<=v;j++) dp[j]=max(dp[j],dp[j-w[i]]+c[i]); cout<<dp[v]<<endl; } return 0; }
③ 多重背包
有n种物品和一个容量为v的背包。第i种物品最多有num[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
#include<iostream> #include<algorithm> #include<cstring> using namespace std; int main() { int t,v,n,i,j,k,dp[105],num[105],c[105],w[105]; cin>>t; while(t--) { memset(dp,0,sizeof dp); cin>>n>>v; for(i=1;i<=n;i++) scanf("%d%d%d",&c[i],&w[i],&num[i]); for(i=1;i<=n;i++) for(j=1;j<=num[i];j++) for(k=v;k>=c[i];k--) dp[k]=max(dp[k],dp[k-c[i]]+w[i]); cout<<dp[v]<<endl; } return 0; }