hdu 3033 I love sneakers!

来源:互联网 发布:数据库系统实现 豆瓣 编辑:程序博客网 时间:2024/04/23 16:23

题目:

        链接:点击打开链接

题意:

        xx喜欢收集鞋子,n,m,k分别表示鞋子的总数,xx的钱和鞋子的品牌数目。然后给出每个鞋子的信息有:a,是那种品牌,b,鞋子的标价,c,收藏鞋子得到的价值。对于一个收藏家来说,每种品牌的鞋子只收集一种,求出xx能够得到的最大的收藏价值。

算法:

        分组背包问题。

思路:

        m总的钱数是背包容量,k品牌数是组数。用数组结构体保存每种鞋子的信息,d[i][j].w表示第i种品牌的鞋子中的第j个鞋子的标价,d[i][j].v表示第i种品牌的鞋子中的第j个鞋子价值。状态转移方程dp[i][j]表示前i组品牌中用掉j钱得到的最大的价值。状态转移可以是前一组少取一个,即dp[i-1][p-d[i][j].w]+d[i][j].v,也可以是当前组少取一种,即dp[i][p-d[i][j].w]+d[i][j].v。初始化第一组置为0,其他组置为负无穷,因为只有上一组达到要求才能进行下一组,每组必须取一个。

代码:

#include<iostream>#include<cstdio>#include<cstring>using namespace std;struct node{    int v;    int w;}d[20][110];int num[20];int dp[20][10010];int main(){    //freopen("input.txt","r",stdin);    int n,m,k;    int a,b,c;    while(scanf("%d%d%d",&n,&m,&k) != EOF)    {        memset(num,0,sizeof(num));        memset(dp,-1,sizeof(dp));        for(int i=1; i<=n; i++)        {            scanf("%d%d%d",&a,&b,&c);            d[a][num[a]].w = b;            d[a][num[a]].v = c;            num[a]++;//num[a]表示第a组的鞋的个数        }        memset(dp[0],0,sizeof(dp[0]));        for(int i=1; i<=k; i++)        {            for(int j=0; j<num[i]; j++)            {                for(int p=m; p>=d[i][j].w; p--)                {                     if(dp[i-1][p-d[i][j].w] != -1)                        dp[i][p] = max(dp[i][p],dp[i-1][p-d[i][j].w]+d[i][j].v);                    if(dp[i][p-d[i][j].w] != -1)                        dp[i][p] = max(dp[i][p],dp[i][p-d[i][j].w]+d[i][j].v);                }            }        }        if(dp[k][m] == -1)            printf("Impossible\n");        else            printf("%d\n",dp[k][m]);    }    return 0;}


0 0