邮票问题

邮票问题

【问题描述】

      给定一个信封,最多只允许粘贴N(N<=100)张邮票,我们现在有m(m<=100)种邮票,面值分别为:x1,x2,…….xm(xi<=255,为正整数),并假设各种邮票都有足够多张.

       要求计算所能获得的邮资最大范围,即求最大值MAX,使在1—MAX之间的每一个邮资值都能得到.

       例如:N=4,2种邮票,面值分别为1,4,于是可以得到1----10,12,13,16分的邮资,由于不能得到11分和15,所有邮资的最大范围是Max=10.      

 

【样例输入】

 从键盘输入一个文本文件的文件名,该文件第1行为最多粘贴的邮票数N;2行为邮票种数m,以下m行各有一个数字,表示邮票的面值xi.:

4

1

4

 

【样例输出】

Max=10


【算法分析】

递推:

设 :f[i] (f[i] 指 i 面值所需的最少张邮票)

起始值 f[1]=1;

开始判断有没有面值 1 的邮票,若没有直接输出;

我们举个例子,比如拿 5 来说

找出 5 能整除的一个邮票,且所有符合条件的邮票面值中它最大;f[i] 等于 5 除以它;

再用一个 for:

for(i=1;i<=i1/2;i++)
 if(f[i1]>f[i]+f[i1-i]) f[i1]=f[i]+f[i1-i];

枚举出 i 面值用两个数所需的最少邮票的最小差;

5:1+4

5:2+3


#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
	int i,i1=0,n,m,a[10001],f[10001];
	scanf("%d%d",&n,&m);
	
	bool b=false;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		if(a[i]==1) b=true; 
	}
	
	if(!b) printf("Max=0");
	else 
	{
		i1=1;f[i1]=1;
		do{
			i1++;
			for(i=1;i<=n;i++)
			 if(i1%a[i]==0)
			  if(f[i1]==0) 
			   f[i1]=i1/a[i];
			  else f[i1]=min(f[i1],i1/a[i]);
	
			for(i=1;i<=i1/2;i++)
			 if(f[i1]>f[i]+f[i1-i]) f[i1]=f[i]+f[i1-i];
			
			if(f[i1]>m || f[i1]==0) break;
		}while(true);
		printf("Max=%d",i1-1);
	}
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值