首页 > ACM题库 > HDU-杭电 > HDU 3348-coins-贪心-[解题报告]HOJ
2014
03-16

HDU 3348-coins-贪心-[解题报告]HOJ

coins

问题描述 :

"Yakexi, this is the best age!" Dong MW works hard and get high pay, he has many 1 Jiao and 5 Jiao banknotes(纸币), some day he went to a bank and changes part of his money into 1 Yuan, 5 Yuan, 10 Yuan.(1 Yuan = 10 Jiao)
"Thanks to the best age, I can buy many things!" Now Dong MW has a book to buy, it costs P Jiao. He wonders how many banknotes at least,and how many banknotes at most he can use to buy this nice book. Dong MW is a bit strange, he doesn’t like to get the change, that is, he will give the bookseller exactly P Jiao.

输入:

T(T<=100) in the first line, indicating the case number.
T lines with 6 integers each:
P a1 a5 a10 a50 a100
ai means number of i-Jiao banknotes.
All integers are smaller than 1000000.

输出:

T(T<=100) in the first line, indicating the case number.
T lines with 6 integers each:
P a1 a5 a10 a50 a100
ai means number of i-Jiao banknotes.
All integers are smaller than 1000000.

样例输入:

3
33 6 6 6 6 6
10 10 10 10 10 10
11 0 1 20 20 20

样例输出:

6 9
1 10
-1 -1

点击打开链接

/*

分析:

求最少的纸币数目时,直接用贪心就可以了;

求最多的纸币数目时,要考虑用较小的纸币来补较大的纸币,只有这样才能使数目最多,

但开始用小的补时,需要先找到满足条件的最小纸币总数对应的i值。。。

2013-04-22

*/

#include"stdio.h"
#include"string.h"
int min(int a[],int num[],int p,int sum[])
{
	int i;
	int ans=0;
	for(i=5;i>1;i--)
	{
		if(p>=num[i]*a[i])
		{
			ans+=num[i];
			p-=num[i]*a[i];
		}
		else
		{
			ans+=p/a[i];
			p%=a[i];
		}
	}
	if(p>num[1])return -1;
	else return ans+p;
}
int max(int a[],int num[],int p,int sum[])
{
	int i;
	int ans=0;
	for(i=5;i>1;i--)
	{
		if(p<=sum[i-1])continue;
		else
		{
			int t;
			//先用满足条件的最大面值,如果有余数,所用张数+1,
			//不足的部分用较小面值的进行补
			t=((p-sum[i-1])/a[i])+(((p-sum[i-1])%a[i])?1:0);
			ans+=t;
			p-=t*a[i];
		}
	}
	if(p>num[1])return -1;
	else return ans+p;
}
void dp(int a[],int num[],int p)
{
	int i;
	int sum[6]={0};
	sum[1]=num[1];
	for(i=2;i<=5;i++)
		sum[i]=sum[i-1]+a[i]*num[i];
	int mmin,mmax;
	mmin=min(a,num,p,sum);
	if(mmin==-1)printf("-1 -1\n");
	else
	{
		mmax=max(a,num,p,sum);
		if(mmax==-1)printf("-1 -1\n");
		else
			printf("%d %d\n",mmin,mmax);
	}
}
int main()
{
	int a[6]={0,1,5,10,50,100};
	int i,p;
	int num[6];
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int sum;
		sum=0;
		scanf("%d",&p);
		for(i=1;i<6;i++)
		{
			scanf("%d",&num[i]);
			sum+=num[i]*a[i];
		}
		if(sum<p)printf("-1 -1\n");
		else dp(a,num,p);
	}
	return 0;
}

参考:http://blog.csdn.net/yangyafeiac/article/details/8834940