HDU打怪升级之Coin Change(2069)

问题链接:http://acm.hdu.edu.cn/showproblem.php?pid=2069

问题描述:

Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make changes with these coins for a given amount of money.

For example, if we have 11 cents, then we can make changes with one 10-cent coin and one 1-cent coin, or two 5-cent coins and one 1-cent coin, or one 5-cent coin and six 1-cent coins, or eleven 1-cent coins. So there are four ways of making changes for 11 cents with the above coins. Note that we count that there is one way of making change for zero cent.

Write a program to find the total number of different ways of making changes for any amount of money in cents. Your program should be able to handle up to 100 coins.

输入:

 The input file contains any number of lines, each one consisting of a number ( ≤250 ) for the amount of money in cents.

栗子输入:

11
26

栗子输出:

4
13

 

问题分析:

题目的大致意思为:现在有50美分、25美分、10美分、5美分和1美分这5类硬币,要用这5类硬币来找零。求出给定的钱数下,总共有几种找零的方法。比如现在有11美分需要找零,则可以通过1个10美分、1个1美分,或者2个5美分、1个1美分、或者1个5美分、6个1美分或者11个1美分这四种方法来找零。
注意:
1.对于0美分有1种方法来找零。
2.硬币的总数最多只有100个。
3.需要找的最大钱数为250。

方法1:
由于限制了硬币总数为100个,找的最大钱数为250,所以可以尝试通过暴力查找来破解。即在给定的钱数下,遍历50美分、25美分、10美分、5美分和1美分能够出现的所有次数情况,找到满足其相加等于给定钱数,并且所需硬币总数不大于100的情况。

方法2:
构造一个二维数组dp,其中dp[i][j]表示的是找零总数为i,总的硬币数为j下的找零方法总数。根据题意,i不大于250,j不大于100。
构造一个一维数组v,其中v[k]表示的现有的硬币面值数,分别可表示1,5,10,25,50这5种面值。
考虑dp[i][j],其可以表示为dp[i-v[k][j-1],k=0~4并且i \geq v[k]的情况总和。例如对于现在需要找零的总数为11,则组成11的种数可是表示为组成10的总数加上组成6的总数加上组成1的总数,这些面值只需要分别加上1个1美分、1个5美分、1个10美分硬币就可以得到11了。

 

参考代码:

1.
#include<iostream>
using namespace std;

int main()
{
	int count,n;
	int count_1,count_5,count_10,count_25,count_50;
	
	while(cin>>n)
	{
		count=0;
		for(count_50=0;count_50<=n/50;count_50++)
			for(count_25=0;count_25<=n/25-2*count_50;count_25++)
				for(count_10=0;count_10<=n/10-5*count_50;count_10++)
					for(count_5=0;count_5<=n/5-2*count_10;count_5++)
						for(count_1=0;count_1<=100;count_1++)
							if(50*count_50+25*count_25+10*count_10+5*count_5+count_1==n
								&&count_50+count_25+count_10+count_5+count_1<=100)
									count++;
		cout<<count<<endl;
	}
	
	return 0;
}
2.
#include<iostream>
#include<string.h>
using namespace std;
int dp[251][101];
int v[5]={1,5,10,25,50};

int main()
{
	int n;
	memset(dp,0,sizeof(dp));
	dp[0][0]=1;
	for(int i=0;i<5;i++)
		for(int j=v[i];j<=250;j++)
			for(int k=1;k<=100;k++)
				dp[j][k] += dp[j-v[i]][k-1];
	while(cin>>n)
	{
		int sum=0;
		for(int i=0;i<=100;i++)
			sum+=dp[n][i];
		cout<<sum<<endl;
	}
	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值