分组背包问题

\(N\) 组物品和一个容量是 \(V\) 的背包。

每组物品有若干个,同一组内的物品最多只能选一个。
每件物品的体积是 \(v_{ij}\),价值是 \(w_{ij}\),其中 \(i\) 是组号,\(j\) 是组内编号。

求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。

输出最大价值。

输入格式

第一行有两个整数 \(N,V\),用空格隔开,分别表示物品组数和背包容量。

接下来有 \(N\) 组数据:

  • 每组数据第一行有一个整数 \(S_i\),表示第 \(i\) 个物品组的物品数量;
  • 每组数据接下来有 \(S_i\) 行,每行有两个整数 \(v_{ij}, w_{ij}\),用空格隔开,分别表示第 \(i\) 个物品组的第 \(j\) 个物品的体积和价值;

输出格式

输出一个整数,表示最大价值。

数据范围

\(0 \lt N, V \le 100\)
\(0 \lt S_i \le 100\)
\(0 \lt v_{ij}, w_{ij} \le 100\)

输入样例

3 5
2
1 2
2 4
1
3 4
1
4 5

输出样例:

8

代码实现

#include<bits/stdc++.h>
using namespace std;

const int N=110;
int f[N][N];  //只从前i组物品中选,当前体积小于等于j的最大值
int v[N][N],w[N][N],s[N];   //v为体积,w为价值,s代表第i组物品的个数
int n,m,k;

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>s[i];
        for(int j=0;j<s[i];j++){
            cin>>v[i][j]>>w[i][j];  //读入
        }
    }

    for(int i=1;i<=n;i++){
        for(int j=0;j<=m;j++){
            f[i][j]=f[i-1][j];  //不选
            for(int k=0;k<s[i];k++){
                if(j>=v[i][k])     f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);  
            }
        }
    }
    cout<<f[n][m]<<endl;
}
posted @ 2023-08-30 14:09  LongDz  阅读(21)  评论(0)    收藏  举报