// 分組背包變形,要求每組物品最少取1次
// 把原來分組背包的循環順序換轉一下就可以了
// 原因是原來分組背包的要求是每組物品最多取1次
// 狀態就是:dp[i][j] 表示前i組物品中,使用j的v所取得的最大值
// 狀態轉移:dp[i][j] = max(dp[i][j], dp[i][j-v[k]]+w[k], dp[i-1][j-v[k]]+w[k]);
// 這裡的順序不能改變,因為題目中存在v為0的物品,如果順序變了,就會加了這個物品2次
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXTYPE 19
#define MAXN 109
#define MAXV 10009
#define INF 0x3f3f3f3f
typedef struct T {
int pos, w[MAXN], v[MAXN];
}Type;
Type arr[MAXN];
int dp[MAXTYPE][MAXV];
int group_knapsack(int max_v, int cnt)
{
for(int i = 0; i <= cnt; i ++) {
if( !i ) {
fill(dp[i], dp[i]+max_v+1, 0); continue;
}
fill(dp[i], dp[i]+max_v+1, -INF);
}
for(int k = 1; k <= cnt; k ++) {
for(int i = 0; i < arr[k].pos; i ++) {
for(int v = max_v; v >= arr[k].v[i]; v --) {
dp[k][v] = max(dp[k][v], dp[k][v-arr[k].v[i]]+arr[k].w[i]);
dp[k][v] = max(dp[k][v], dp[k-1][v-arr[k].v[i]]+arr[k].w[i]);
}
}
}
return dp[cnt][max_v];
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int n, max_v, cnt, idx, v, w;
while( ~scanf("%d %d %d", &n, &max_v, &cnt) ) {
memset(arr, 0, sizeof(arr));
for(int i = 0; i < n; i ++) {
scanf("%d %d %d", &idx, &v, &w);
arr[idx].w[ arr[idx].pos ] = w;
arr[idx].v[ arr[idx].pos ++ ] = v;
}
idx = group_knapsack(max_v, cnt);
if( idx <= 0 ) {
printf("Impossible\n");
}
else {
printf("%d\n", idx);
}
}
return 0;
}
hdu_3033
最新推荐文章于 2020-03-03 16:37:09 发布