--- title: "分组背包问题" created: 2025-11-28 tags: - 算法 --- # 分组背包问题 ## 题目 [分组背包问题](https://www.acwing.com/problem/content/9/) ![[image-6e35e2c5.png]] ## 思路分析 ![[image-1d734ad4.png]] 从另一个角度 多加一个维度 现在是每类物品里选一个 多了个类这一维 但是因为只能选一个 所以还是可以当做01去写 朴素做法 ```cpp #include using namespace std; const int N = 110; //由n种物品变成了n类物品 然后又要在每类里面去选 //所以就是多了一维 int v[N][N],w[N][N],s[N]; int f[N][N]; int n, m; int main() { cin>>n>>m; for(int i=1;i<=n;i++){ cin>>s[i]; for(int j=0;j>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=v[i][k]) f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]); } } } cout< using namespace std; const int N = 110; //由n种物品变成了n类物品 然后又要在每类里面去选 //所以就是多了一维 int v[N][N],w[N][N],s[N]; int f[N]; int n, m; int main() { cin>>n>>m; for(int i=1;i<=n;i++){ cin>>s[i]; for(int j=0;j>v[i][j]>>w[i][j]; } } for(int i=1;i<=n;i++){ //用的上一层的数据 从大到小遍历 for(int j=m;j>=0;j--){ for(int k=0;k=v[i][k]) f[j]=max(f[j],f[j-v[i][k]]+w[i][k]); } } } cout< using namespace std; const int N = 110; int v[N][N],w[N][N],s[N]; int f[N][N]; int n, m; int main() { cin>>n>>m; for(int i=1;i<=n;i++){ cin>>s[i]; for(int j=0;j>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=v[i][k]) f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]); } } } cout< using namespace std; const int N = 110; int v[N][N],w[N][N],s[N]; int f[N]; int n, m; int main() { cin>>n>>m; for(int i=1;i<=n;i++){ cin>>s[i]; for(int j=0;j>v[i][j]>>w[i][j]; } } for(int i=1;i<=n;i++) for(int j=m;j>=0;j--) for(int k=0;k=v[i][k]) f[j]=max(f[j],f[j-v[i][k]]+w[i][k]); cout<