动态规划--分组背包

状态表示 f[i][j]  -------------集合:考虑前 i 组物品,体积不超过 j 的取法的价值的集合

       ------------属性:最大值

状态计算:f ( i , j ) = f ( i-1 , j) , f ( i-1 , j-v1) + w1 ,  f ( i , j ) = f ( i-1 , j-v2) + w2 .....最大值

 1 #include<iostream>
 2 using namespace std;
 3 const int N=110;
 4 int v[N][N],w[N][N],s[N];
 5 int f[N][N];
 6 int main(void){
 7     int n,m;
 8     cin>>n>>m;
 9     for(int i=1;i<=n;i++){
10         cin>>s[i];
11         for(int j=1;j<=s[i];j++){
12             cin>>v[i][j]>>w[i][j];
13         }
14     }
15     for(int i=1;i<=n;i++){
16         for(int j=0;j<=m;j++){
17             f[i][j]=f[i-1][j];
18             for(int k=1;k<=s[i];k++){
19                 if(j>=v[i][k])
20                     f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
21             }
22         }
23     }
24     cout<<f[n][m];
25     return 0;
26 }

 因为只用到了上一层,所以可以用滚动数组。

再因为他后面的列只会用到前面的列,所以从后往前枚举就可以优化到一维了。

 1 #include <iostream>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 const int N = 110;
 7 
 8 int n, m;
 9 int v[N][N], w[N][N], s[N];
10 int f[N];
11 
12 int main()
13 {
14     cin >> n >> m;
15 
16     for (int i = 1; i <= n; i ++ )
17     {
18         cin >> s[i];
19         for (int j = 0; j < s[i]; j ++ )
20             cin >> v[i][j] >> w[i][j];
21     }
22 
23     for (int i = 1; i <= n; i ++ )
24         for (int j = m; j >= 0; j -- )
25             for (int k = 0; k < s[i]; k ++ )
26                 if (v[i][k] <= j)
27                     f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
28 
29     cout << f[m] << endl;
30 
31     return 0;
32 }

 

posted on 2021-01-15 21:21  greenofyu  阅读(132)  评论(0编辑  收藏  举报