HDU 3033------I love sneakers!

来源:互联网 发布:江苏大学网络教学平台 编辑:程序博客网 时间:2024/05/01 01:32

I love sneakers!

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4465    Accepted Submission(s): 1825


Problem Description
After months of hard working, Iserlohn finally wins awesome amount of scholarship. As a great zealot of sneakers, he decides to spend all his money on them in a sneaker store.

There are several brands of sneakers that Iserlohn wants to collect, such as Air Jordan and Nike Pro. And each brand has released various products. For the reason that Iserlohn is definitely a sneaker-mania, he desires to buy at least one product for each brand.
Although the fixed price of each product has been labeled, Iserlohn sets values for each of them based on his own tendency. With handsome but limited money, he wants to maximize the total value of the shoes he is going to buy. Obviously, as a collector, he won’t buy the same product twice.
Now, Iserlohn needs you to help him find the best solution of his problem, which means to maximize the total value of the products he can buy.
 

Input
Input contains multiple test cases. Each test case begins with three integers 1<=N<=100 representing the total number of products, 1 <= M<= 10000 the money Iserlohn gets, and 1<=K<=10 representing the sneaker brands. The following N lines each represents a product with three positive integers 1<=a<=k, b and c, 0<=b,c<100000, meaning the brand’s number it belongs, the labeled price, and the value of this product. Process to End Of File.
 

Output
For each test case, print an integer which is the maximum total value of the sneakers that Iserlohn purchases. Print "Impossible" if Iserlohn's demands can’t be satisfied.
 

Sample Input
5 10000 31 4 62 5 73 4 991 55 772 44 66
 

Sample Output
255
 
 题意:
Iserlohn喜欢收集鞋子,他有M块钱,每双鞋子都有价格b和在他心中的价值c。他要把所有品牌的鞋子都收集齐,问在买到所有品牌鞋子的情况下能得到的最大价值是多少。若不能收集齐所有鞋子,那么输出Impossible。
给你N组数据,M块钱,K个品牌。每组数据包括第几个品牌a,价格b,价值c。
题解:
这是一题分组背包,我们可以将数据按品牌归类,再将所有的品牌排序,要使购买当前品牌的鞋子的结果有意义的条件就是前面所有品牌的鞋子买了至少一双。所以当前有两种情况:设当前为第K种品牌。1、前k-1种品牌的鞋子都买了,但是当前的品牌的鞋子未购买。2、前k-1种品牌的鞋子都买了,并且当前品牌的鞋子也购买了至少一双。
因此可得dp方程:
                                if(dp[i][q-mm[i][j].m]!=-1)
           dp[i][q]=max(dp[i][q],dp[i][q-mm[i][j].m]+mm[i][j].v);
        if(dp[i-1][q-mm[i][j].m]!=-1)
   dp[i][q]=max(dp[i][q],dp[i-1][q-mm[i][j].m]+mm[i][j].v);
我们将开始时的dp设为负值表示当前情况不成立。
在买第一种品牌的时候不需要考虑dp的大小。
这里需要注意的是两个If的顺序问题。
这里if的顺序是不能调换的,因为这里的鞋子只有一双。如果换了位置并且现在剩余的钱足够多就会出现这双鞋子被买了两次的情况。请注意。
参考代码如下:
#include<stdio.h>#include<string.h>#define max(a,b) a>b?a:bstruct node{int m,v;}mm[11][101];int dp[11][10001],num[11];int main(){int n,m,k,nk,nm,nv;while(~scanf("%d%d%d",&n,&m,&k)){memset(num,0,sizeof(num));for(int i=1;i<=n;i++){    scanf("%d%d%d",&nk,&nm,&nv);    mm[nk][num[nk]].m=nm;    mm[nk][num[nk]].v=nv;    num[nk]++; }memset(dp,-1,sizeof(dp));for(int i=0;i<=m;i++)    dp[0][i]=0;        for(int i=1;i<=k;i++)        {        for(int j=0;j<num[i];j++)        {        for(int q=m;q>=mm[i][j].m;q--)        {        if(dp[i][q-mm[i][j].m]!=-1)            dp[i][q]=max(dp[i][q],dp[i][q-mm[i][j].m]+mm[i][j].v);        if(dp[i-1][q-mm[i][j].m]!=-1)    dp[i][q]=max(dp[i][q],dp[i-1][q-mm[i][j].m]+mm[i][j].v);            }        }        }        if(dp[k][m]<0)            printf("Impossible\n");        else     printf("%d\n",dp[k][m]);}return 0;} 


0 0
原创粉丝点击