洛谷P1757 通天之分组背包 题解
本题做法
- 分组背包 DP。
思路
这题是经典的分组背包模板题。我们可以对每个物品的所属组和对每个组的物品数量及具体物品进行记录,因为每组至多只能选择 1 个物品,所以我们可以枚举组数的同时对当前组内的第几个物品进行枚举,然后接下来就和普通的 0-1 背包 DP 差不多了。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1005;
int n,m,t,v[N],w[N],z[N],dp[N],a[N],b[N][N];
//a[i]:第i组的个数
//b[i][j]:第i组的第j个物品
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>m>>n;
for(int i=1;i<=n;i++){
cin>>v[i]>>w[i]>>z[i];
t=max(t,z[i]);
a[z[i]]++;
b[z[i]][a[z[i]]]=i;
}
for(int i=1;i<=t;i++){
for(int j=m;j>=0;j--){
for(int k=1;k<=a[i];k++){
if(j>=v[b[i][k]]) dp[j]=max(dp[j],dp[j-v[b[i][k]]]+w[b[i][k]]);
}
}
}
cout<<dp[m]<<endl;
return 0;
}