HDU - 1114 Piggy-Bank【动态规划 完全背包】

版权声明:文章原创,未经允许请勿转载 https://blog.csdn.net/DanBo_C/article/details/89891987

译文

问题描述
在ACM可以做任何事情之前,必须准备预算并获得必要的财务支持。此行动的主要收入来自不可逆转的捆绑资金(IBM)。背后的想法很简单。每当一些ACM成员有任何小钱时,他拿走所有硬币并将它们扔进存钱罐。你知道这个过程是不可逆转的,硬币不能在不打破猪的情况下被移除。经过足够长的时间,存钱罐里应该有足够的现金来支付需要支付的所有东西。

但是存钱罐存在很大问题。无法确定内部有多少钱。因此,我们可能会将猪分成碎片,但却发现没有足够的钱。显然,我们希望避免这种不愉快的情况。唯一的可能性是称重存钱罐并试图猜测里面有多少硬币。假设我们能够确切地确定猪的重量并且我们知道给定货币的所有硬币的重量。然后,我们可以保证在存钱罐中有一些最低金额。你的任务是找出最坏的情况,并确定存钱罐内的最低现金数量。我们需要你的帮助。不再过早破猪!

输入
输入由T个测试用例组成。它们的数量(T)在输入文件的第一行给出。每个测试用例都以包含两个整数E和F的行开头。它们表示空猪和装满硬币的猪的重量。两种重量均以克为单位。没有猪的体重超过10公斤,这意味着1 <= E <= F <= 10000.在每个测试用例的第二行,有一个整数N(1 <= N <= 500)给出了数字以给定货币使用的各种硬币。在此之后正好是N行,每行指定一种硬币类型。这些行包含两个整数,Pand W(1 <= P <= 50000,1 <= W <= 10000)。P是以货币单位表示的硬币值,W是以克为单位的重量。

产量
为每个测试用例打印一行输出。该行必须包含句子“存钱罐中的最小金额是X.” 其中X是使用给定总重量的硬币可以实现的最小金额。如果无法准确达到重量,请打印一行“这是不可能的”。

样本输入
3
10 110
2
1 1
30 50
10 110
2
1 1
50 30
1 6
2
10 3
20 4

样本输出
存钱罐里的最低金额是60。
存钱罐里的最低金额是100。
这是不可能的。

解题思路

和01背包的差别不是太大
注意点

  1. 注意内存循环 和 该题为最坏的结果,即最小价值
 for(int i=1;i<=num;i++)
		for(int j=a[i].w;j<=v;j++)
			dp[j] = min(dp[j-a[i].w]+a[i].p,dp[j]);
  1. 数组置为无穷大,不能用
memset(dp,INF,sizeof(dp));

代码

#include<iostream>
using namespace std;
#define min(a,b) (a<b?a:b)
#define INF 0x3f3f3f3f
struct node
{
	int p;
	int w;
}a[10005];
int N,num,p,w;
int in,ax;
double dp[10005];

int main()
{
	cin>>N;
	while(N--)
	{
		cin>>in>>ax;
		int v = ax-in;
		cin>>num;
		for(int i=1;i<=num;i++)
			cin>>a[i].p>>a[i].w;
		//memset(dp,INF,sizeof(dp));
		for(int i=0;i<=v;i++)
			dp[i]=INF;
		dp[0] = 0;

		for(int i=1;i<=num;i++)
			for(int j=a[i].w;j<=v;j++)
				dp[j] = min(dp[j-a[i].w]+a[i].p,dp[j]);

		if(dp[v]>=INF)
			cout<<"This is impossible."<<endl;
		else
			cout<<"The minimum amount of money in the piggy-bank is "<<dp[v]<<"."<<endl;
			
	}
}

猜你喜欢

转载自blog.csdn.net/DanBo_C/article/details/89891987
今日推荐