程序设计与算法6-3:Coin Change

题目
给出不同面额的硬币以及一个总金额. 写一个方法来计算给出的总金额可以换取的最少的硬币数量. 如果已有硬币的任意组合均无法与总金额面额相等, 那么返回 -1.

样例一

输入:
1, 2, 5
11
输出: 3
解释: 11 = 5 + 5 + 1
1
2
3
4
5
样例二

输入: 
2
3
输出: -1

思路

1.确定状态

·开一个数组,数组的每个元素f[i]或者f[i][j]代表什么;

·最后一步:一定有一枚最后的硬币ak,除掉这一枚硬币其余的为27-ak;

关键1:不知道k-1枚硬币怎么拼出27-ak的,不知道ak和k,但是确定前面的硬币拼出来27-ak;

关键2:因为是最优策略,所以拼出27-ak的硬币数一定要少;

·子问题:最少用多少枚硬币可以拼出27-ak

简化定义,设状态f(X)=最少用多少枚硬币拼出X;   

如果ak为2、5、7,f(27)=f(27-x)+1;

最少的硬币数:f(27)=min{f(27-2)+1,f(27-5)+1;f(27-7)+1};

递归解法:

2. 转移方程

·设状态f[X]=最少用多少枚硬币拼出X;

·对于任意X,f[X]=min{f[X-2]+1,f[X-5]+1,f[X-7]+1};

3.舒适条件和边界情况

·f[X]=min{f[X-2]+1,f[X-5]+1,f[X-7]+1};

·X-2,X-5,X-7小于0:如果不能拼出Y,就定义f[Y]=正无穷,f[1]=min{f[-1]+1,f[-4]+1,f[-6]+1};

·初始条件(用转移方程算不出来,需要手工定义):f[0]=0;

4.计算顺序

·拼出X所需要的最少硬币数:f[X]=min{f[X-2]+1,f[X-5]+1,f[X-7]+1};

·初始条件:f[0]=0;

·然后计算f[1],f[2]...f[27];

·当我们计算到f[X]时,f[X-2],f[X-5],f[X-7]已经得到了

 递推:

#include<iostream>
#include<cstdio>
#include<algorithm>
int f[30];
using namespace std;
int main()
{
	int coin1,coin2,coin3,n;
	cin>>coin1>>coin2>>coin3;
	cin>>n;
	f[0]=0;
	int Max=n/coin1+1;
	for(int i=1;i<=n;i++)
	{
		int zero,one,two;
		if(i>=coin1)
			zero=f[i-coin1]+1;
		else
			zero=Max;
		if(i>=coin2)
			one=f[i-coin2]+1;
		else
			one=Max;
		if(i>=coin3)
			two=f[i-coin3]+1;
		else
		 	two=Max;		
	 	f[i]=min(zero,min(one,two)); 
	 } 
	 cout<<f[n];
	return 0;
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值