hdu 3348 (数学+贪心)

点击打开链接


/*


分析:

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

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

但开始用小的补时,需要先找到满足条件的最小纸币总数对应的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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值