• hdu3033 I love sneakers!


    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 3 1 4 6 2 5 7 3 4 99 1 55 77

    2 44 66

    这题属于分组背包,但和多个取一个的不同,这里是至少取一个,可以设dp[i][j]表示前i组花费j元所能得到的最大价值,dp[i][j]先都初始化为-1,然后把dp[0][i]都记为0,在判断的时候要加上两个if,就是如果转移过来的状态是-1,那么这个状态已经不能成立了,所以当前这个状态肯定不能成立,这一点可以动笔画一下。

    #include<stdio.h>
    #include<string.h>
    int max(int a,int b){
    	return a>b?a:b;
    }
    int dp[13][10060],num[13];
    struct node{
    	int w,v;
    }a[13][105];
    int main()
    {
    	int n,m,i,j,k,lei,c,d,e;
    	while(scanf("%d%d%d",&n,&m,&lei)!=EOF)
    	{
    		memset(a,0,sizeof(a));
    		memset(num,0,sizeof(num));
    		for(i=1;i<=n;i++){
    			scanf("%d%d%d",&c,&d,&e);
    			num[c]++;a[c][num[c]].w=d;a[c][num[c]].v=e;
    		}
    		memset(dp,-1,sizeof(dp));
    		//for(i=0;i<=lei;i++)dp[i][0]=0;注意:这里不能把每一行的dp[i][0]记为0,因为这样前面一行未满足至少取1个的条件是-1的话,那么这行也应该是-1,不是0.
    		for(i=0;i<=m;i++)dp[0][i]=0;
    		for(i=1;i<=lei;i++){
    			for(k=1;k<=num[i];k++){
    				for(j=m;j>=a[i][k].w;j--){
    					if(dp[i][j-a[i][k].w]!=-1)//这里两个if不能换顺序,因为第一个if是对这一组的多个背包进行挑选,
    					dp[i][j]=max(dp[i][j],dp[i][j-a[i][k].w]+a[i][k].v);//如果先进行第二个if,那么可能当前的dp[i][j]不再为-1, 
    					if(dp[i-1][j-a[i][k].w]!=-1)//然后运行第一个if的时候可能会产生冲突,
    					dp[i][j]=max(dp[i][j],dp[i-1][j-a[i][k].w]+a[i][k].v);//即原来不能成立的状态变为可能然后再进行背包运算 。 
    				}
    			}
    		}
    		if(dp[lei][m]<0)printf("Impossible
    ");
    	    else printf("%d
    ",dp[lei][m]);
    	}
    	return 0;
    }


  • 相关阅读:
    通过AIR Native Extension在AIR应用中加入iAd广告(一) —— Flash Builder篇
    使用MonoTouch.SQLite简化用户界面开发
    常见的几种分支开发方式
    给对象增加一个简单的自定义事件机制
    WCF 4.5:配置文件更小,对ASP.NET的支持更好
    MongoDB中的Group By
    SQL Server 2012大幅增强了TSQL
    编程珠玑:对DAO层的一点修改
    《The Elements of User Experience》读书笔记
    ORM工具LLBLGen Pro 3.5发布
  • 原文地址:https://www.cnblogs.com/herumw/p/9464722.html
Copyright © 2020-2023  润新知