HDU 3033 分组背包
给出N个物品。M金钱。W种类
给出N个物品的性质:所属种类,花费。价值
求每一种类物品至少一个的前提下,所能购买到的最大价值
dp[i][k]表示在第i种物品。总花费为k的最大价值
dp[i][k]=Max(dp[i][k],dp[i][k-a[i][j].p]+a[i][j].v);
dp[i][k]=Max(dp[i][k],dp[i-1][k-a[i][j].p]+a[i][j].v);
一定要先推断从本组更新,避免同一个物品被用了两次
dp[i][k]==-1 表示该状态不可到达
#include "stdio.h" #include "string.h" struct node { int p,v; }a[11][101]; int dp[11][10010]; int c[11]; int Max(int a,int b) { if (a<b) return b; else return a; } int main() { int n,m,i,j,k,x,ans,w; while (scanf("%d%d%d",&n,&m,&w)!=EOF) { memset(a,0,sizeof(a)); memset(c,0,sizeof(c)); for (i=1;i<=n;i++) { scanf("%d",&x); c[x]++; scanf("%d%d",&a[x][c[x]].p,&a[x][c[x]].v); } memset(dp,-1,sizeof(dp)); dp[0][0]=0; for (i=1;i<=w;i++) for (j=1;j<=c[i];j++) for (k=m;k>=a[i][j].p;k--) { if (dp[i][k-a[i][j].p]!=-1) { dp[i][k]=Max(dp[i][k],dp[i][k-a[i][j].p]+a[i][j].v); } if (dp[i-1][k-a[i][j].p]!=-1) { dp[i][k]=Max(dp[i][k],dp[i-1][k-a[i][j].p]+a[i][j].v); } } ans=-1; for (i=0;i<=m;i++) ans=Max(ans,dp[w][i]); if (ans==-1) printf("Impossible\n"); else printf("%d\n",ans); } return 0; }