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;
}




posted @ 2016-01-08 21:25  blfshiye  阅读(142)  评论(0编辑  收藏  举报