hdu 1114 Piggy-Bank 【完全背包】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 34490    Accepted Submission(s): 17088
汉化版:

在ACM能够开展之前,必须准备预算,并获得必要的财力支持。该活动的主要收入来自于不可逆的捆绑金钱(IBM)。思路很简单。任何时候,某位ACM会员有少量的钱时,他将所有的硬币投入到小猪储钱罐中。这个过程不可逆,因为只有把小猪储钱罐打碎才能取出硬币。在足够长的时间之后,小猪储钱罐中有了足够的现金,用于支付ACM活动所需的花费。

但是,小猪储钱罐存在一个大的问题,即无法确定其中有多少钱。因此,我们可能在打碎小猪储钱罐之后,发现里面的钱不够。显然,我们希望避免这种不愉快的情况。唯一的可能是,称一下小猪储钱罐的重量,并尝试猜测里面的有多少硬币。假定我们能够精确判断小猪储钱罐的重量,并且我们也知道给定币种的所有硬币的重量,那么,我们可以保证小猪储钱罐中最少有多少钱。

你的任务是找出最差的情形,即判断小猪储钱罐中的硬币最少有多少钱。我们需要你的帮助。不能再贸然打碎小猪储钱罐了!

输入

输入包含T组测试数据。输入文件的第一行,给出了T的值。

对于每组测试数据,第一行包含E和F两个整数,它们表示空的小猪储钱罐的重量,以及装有硬币的小猪储钱罐的重量。两个重量的计量单位都是g(克)。小猪储钱罐的重量不会超过10 kg(千克),即1 <= E <= F <= 10000。每组测试数据的第二行,有一个整数N(1 <= N <= 500),提供了给定币种的不同硬币有多少种。接下来的N行,每行指定一种硬币类型,每行包含两个整数P和W(1 <= P <= 50000 ,1 <= W <= 10000).P是硬币的金额(货币计量单位); W是它的重量,以g(克)为计量单位。

输出

对于每组测试数据,打印一行输出。每行必须包含句子“存钱罐中的最小金额是X.”其中,X表示对于给定总重量的硬币,所能得到的最少金额。如果无法恰好得到给定的重量,则打印一行“这是不可能的。”

示例输入


10 110 

1 1 
30 50 
10 110 

1 1 
50 30 
1 6 

10 3 
20 4

示例输出

存钱罐中
的最低金额是60.存钱罐中的最低金额是100. 
这是不可能的。

思路:完全背包,动态规划的应用!

//dp[i] : 表示存钱罐空间为 i 的最小价值;

空间为0时的价值为0,其他都初始化为正无穷! 

#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=0x3f3f3f3f;
int main()
{
	int dp[10002],a[10002],b[10001];
	int t;
	scanf("%d",&t);
	while(t--)
	{   
	    memset(dp,maxn,sizeof(dp));   //初始化
	    dp[0]=0;    
		int m,m1;
		scanf("%d %d",&m,&m1);
		m1=m1-m;
		int n;
		scanf("%d",&n);
		for(int i=0;i<n;i++)
		  scanf("%d %d",&a[i],&b[i]);
		for(int i=0;i<n;i++)  //完全背包 
		{
			for(int j=b[i];j<=m1;j++)
			{
				dp[j]=min(dp[j],dp[j-b[i]]+a[i]);
			}
		}
		if(dp[m1]!=maxn)
		   printf("The minimum amount of money in the piggy-bank is %d.\n",dp[m1]);
		else
		   printf("This is impossible.\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/LOOKQAQ/article/details/81564404