ACM硬币问题

这是一道ACM之上的题目,在网上看到的大多是用贪心算法完成的,而贪心策略就是大面额的钱币尽可能的取,这样貌似没什么问题,比如15元,按照贪心策略来说尽可能的去面额的的及一张10+一张5。确实这些情况下,该贪心策略是没问题的,但是若是11呢,在这种情况下,按照贪心策略,就是取一张10,但是问题来了,没有1元的,就没有答案,而事实是取一张五元+三张2元的,这是最优的选择,所以对于该问题贪心策略是不可行的(原因我大概懂一点,但是说不清楚)。

那现在再来考虑这个问题,现在记d(i)=j:及最少需要j张钱币才可以凑齐i元,

那么不难知

d(0)=0;d(1)=INF;d(2)=d(5)=d(10)=d(20)=d(50)=d(100)=1;

记d(i)=INF,i<0;其中INF代表无穷大;

那么其余i,d(i)=min(d(i-2),d(i-5),d(i-10),d(i-20),d(i-50),d(i-100))+1;

这样偶们就可以通过递推得到最后的解,这个再算法里应该叫做DP(动态规划)。

关键代码片段:

public void SequentialDerivation(int n){
		a=new int[n+1];
		for(int i=1;i<=n;i++){
			if(i==2||i==5||i==10||i==20||i==50||i==100)	a[i]=1;
			else if(i<2)	a[i]=TestCion.INFINITE;
			else if(i<5)	a[i]=a[i-2]+1;
			else if(i<10)	a[i]=Math.min(a[i-2], a[i-5])+1;
			else if(i<20)	a[i]=Math.min(Math.min(a[i-2], a[i-5]), a[i-10])+1;
			else if(i<50)	a[i]=Math.min(Math.min(a[i-2], a[i-5]), Math.min(a[i-10], a[i-20]))+1;
			else if(i<100)	a[i]=TestCion.min(Math.min(a[i-2], a[i-5]), Math.min(a[i-10], a[i-20]),a[i-50])+1;
			else	a[i]=TestCion.min(Math.min(a[i-2], a[i-5]), Math.min(a[i-10], a[i-20]),Math.min(a[i-50], a[i-100]))+1;
		}
		for (int i = 1; i < a.length; i++) {
			if((i-1)%10==0)	System.out.println();
			if(a[i]<TestCion.INFINITE)
				System.out.print(String.format("%-10d", a[i]));
			else
				System.out.print(String.format("%-10s", "No Answer"));
			
		}
	}
public static int min(int a,int b,int c){
		//求三个数的最小值
		a=a<b?a:b;
		return a<c?a:c;
	}
但是这样不难发现,若是问题上万上亿,那么开辟的数组也就足够浪费空间,那是不是有别的什么好的方法来解决这道题???

下面我可能说得很乱,因为我也不知道该怎么说清楚。

先说第一点,首先我们注意到,这道题和我们现实生活中的钱币的划分很相似,但是现实中还多一个1元的,我们知道这样的话我们可以划分所有的>1的钱币,而且一开始讲的贪心策略是适用的,

其次我们注意到在这种钱币的划分中只有5是奇数,其他均为偶数,这就导致对于i若为奇数,则必有一张5,若为偶数,则必定没有5,因为若有5,则必定是偶数个5,而没有两个5就可化为一个10,所以有偶数个5的绝对不是最优的。

然后我乱想一通又得到两个算法:

一个太复杂,不写;

另一个:

public int greedyAlgorithm(int n){
		int total=0;
		if(n==1||n==3)
			return INFINITE;
		if(n%2==1)
			total++;
		total+=n/100;n%=100;
		total+=n/50;n%=50;
		total+=n/20;n%=20;
		total+=n/10;n%=10;
		total+=n/2;n%=2;
		return total;
	}
这个是但心算法,先对奇数处理,若为奇数,必有一张5,即total++;

最后我做一个大胆的假设:

若是最小的奇数存在时,则对奇数的钱币时可以采用贪心策略;(待验证)

若是最小的偶数存在时,则对偶数的钱币时可以采用贪心策略.(待验证)



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值