hdu 3535
地址:http://acm.hdu.edu.cn/showproblem.php?pid=3535
题意:混乱背包,s=0,至少选一种,s=1,最多选一种,s=2,随意选。
mark:分别三种情况背包。初始化的时候不能直接把dp[i-1][j]赋值给dp[i][j],必须取最大值。
代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> const int N = 110; int n,t,m,s; int v[N],w[N]; int dp[N][N]; int i,f; int max(int a, int b) {return a > b ? a : b;} void solve1() { for(int k = 1; k <= m; k++) for(int j = t; j >= v[k]; j--) { if(dp[i][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i][j-v[k]]+w[k]); if(dp[i-1][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i-1][j-v[k]]+w[k]); } } void solve2() { for(int j = t; j >= 0; j--) { dp[i][j] = max(dp[i][j], dp[i-1][j]); for(int k = 1; k <= m; k++) if(j >= v[k] && dp[i-1][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i-1][j-v[k]]+w[k]); } } void solve3() { for(int k = 1; k <= m; k++) for(int j = t; j >= 0; j--) { dp[i][j] = max(dp[i-1][j], dp[i][j]); //找了好长时间的错!!! if(j >= v[k] && dp[i][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i][j-v[k]]+w[k]); if(j >= v[k] && dp[i-1][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i-1][j-v[k]]+w[k]); } } int main() { int j,k; while(~scanf("%d%d", &n, &t)) { memset(dp, -1, sizeof(dp)); dp[0][0] = 0; f = 0; for(i = 1; i <= n; i++) { scanf("%d%d", &m, &s); for(j = 1; j <= m; j++) scanf("%d%d", v+j, w+j); if(f) continue; if(s == 0) solve1(); else if(s == 1) solve2(); else solve3(); for(j = 0; j <= t; j++) if(dp[i][j] != -1) break; if(j == t+1) f = 1; } int ans = -1; for(i = 0; i <= t; i++) ans = max(ans, dp[n][i]); printf("%d\n", ans); } return 0; }