背包问题模板

1. 01背包问题

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。第 i 件物品的体积是 vi,价值是 wi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 1010;
 6 int n, m;
 7 int dp[maxn];
 8 int main(){
 9     cin >> n >> m;
10     for(int i = 1; i <= n; i++){
11         int v, w;
12         cin >> v >> w;
13         for(int j = m; j >= v; j--)//体积从大到小枚举
14             dp[j] = max(dp[j], dp[j - v] + w);
15     }
16     cout << dp[m] << endl;
17     return 0;
18 }

 

2. 完全背包问题

有 N 件物品和一个容量是 V 的背包。每件物品可以使用无限次。第 i 件物品的体积是 vi,价值是 wi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 1010;
 6 int n, m;
 7 int dp[maxn];
 8 int main(){
 9     cin >> n >> m;
10     for(int i = 1; i <= n; i++){
11         int v, w;
12         cin >> v >> w;
13         for(int j = v; j <= m; j++)//体积从小到大枚举
14             dp[j] = max(dp[j], dp[j - v] + w);
15     }
16     cout << dp[m] << endl;
17     return 0;
18 }

 

3. 多重背包问题

有 N 件物品和一个容量是 V 的背包。第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。输出最大价值。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int w[1000];
 4 int v[1000];
 5 int m[1000];
 6 int dp[1000];
 7 int main(){
 8     int a,W,n;
 9     cin>>a;
10     while(a--){
11         memset(dp,0,sizeof(dp));
12         cin>>W>>n;
13         for(int i=0;i<n;i++){
14             cin>>w[i]>>v[i]>>m[i];
15         }
16         for (int i=0;i<n;i ++){
17             int num =m[i];
18             for (int k=1; num >0;k<<=1){
19                 int mul =min (k,num );
20                 for (int j=W;j >=w[i]* mul;j --){
21                     dp[j]= max (dp[j],dp[j-w[i]* mul ]+v[i]* mul );
22                 }
23             num -= mul;
24             }
25         }
26         cout<<dp[W]<<endl;
27     }
28     return 0;
29 }

 

单调队列优化:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,m,l,r;
 4 const int N=1e5+7;
 5 int dp[N],q[N],num[N];
 6  
 7 int main(){
 8     int v,w,c;
 9     scanf("%d%d",&n,&m);            
10     for(int i=1;i<=n;i++){
11         scanf("%d%d%d",&v,&w,&c);   //v 体积  w  价值  c 数量
12         if(c>m/v) c=m/v;
13         for(int j=0;j<v;j++){
14             l=r=1;
15             for(int k=0;k<=(m-j)/v;k++){
16                 int tmp=dp[k*v+j]-k*w;
17                 while(l<r&&q[r-1]<=tmp) r--;
18                 q[r]=tmp;
19                 num[r++]=k;
20                 while(l<r&&k-num[l]>c) l++;         
21                 dp[k*v+j]=max(dp[k*v+j],q[l]+k*w);  
22             }
23         }
24     }
25     printf("%d\n",dp[m]);
26 
27     return 0;
28 }
posted @ 2019-10-28 16:28  yya雨  阅读(111)  评论(0编辑  收藏  举报