I love sneakers! 分组双肩包DP
I love sneakers! 分组背包DP
/*一道分组背包的题。比赛的时候循环顺序整反了。悲剧了。 f[i][j]=max(max(f[i][j],f[i-1][j-c[i][p]]+w[i][p]),f[i][j-c[i][p]]+w[i][p]); 表示取到前i个牌子时取到的最大的价值。而每个牌子必须至少取一次。每个物品最多取一次。 f[i][j], f[i][j-c[i][p]]+w[i][p] 保证在同一牌子内取或不取。 f[i-1][j-c[i][p]]+w[i][p])在不同的牌子内取或不去。如果最后的状态都无法更新仍为-1.则不满足条件。 #include <stdio.h> #include <vector> #include <iostream> #define maxn 10001 int f[11][maxn]; int max(int a,int b) { return a>b?a:b; } using namespace std; int main() { int n,m,k,t,a,b; vector<int> c[maxn]; vector<int> w[maxn]; while(scanf("%d%d%d",&n,&m,&k)==3) { for(int i=1; i<=n; i++) { scanf("%d%d%d",&t,&a,&b); c[t].push_back(a); w[t].push_back(b); } for(int i=1; i<=k; i++) for(int j=0; j<=maxn; j++) f[i][j]=-1; for(int i=1; i<=k; i++) for(int p=0; p<c[i].size();p++) for(int j=m; j>=0; j--) if(j>=c[i][p]) { f[i][j]=max(max(f[i][j],f[i-1][j-c[i][p]]+w[i][p]),f[i][j-c[i][p]]+w[i][p]); } if(f[k][m]==-1) printf("Impossible\n"); else printf("%d\n",f[k][m]); for(int i=0;i<maxn;i++) { c[i].clear(); w[i].clear(); } } return 0; }