UVA 674 Coin Change 换硬币 经典dp入门题

题意:有1,5,10,25,50五种硬币,给出一个数字,问又几种凑钱的方式能凑出这个数。

经典的dp题。。。可以递推也可以记忆化搜索。。。

我个人比较喜欢记忆化搜索,递推不是很熟练。


记忆化搜索:很白痴的算法,直接交给下一层去算,算完记录下来以免之后重复算。

代码:

 

/*
*  Author:      illuz <iilluzen[at]gmail.com>
*  Blog:        http://blog.csdn.net/hcbbt
*  File:        _uva674.cpp
*  Create Date: 2013-09-20 14:00:42
*  Descripton:  dp, memorial 
*/

#include <cstdio>
#include <cstring>
const int MAXN = 8000;
const int coin[5] = {1, 5, 10, 25, 50};
int n;
long long dp[MAXN][5];

long long solve(int i, int s) {
	if (dp[s][i] != -1)
		return dp[s][i];
	dp[s][i] = 0;
	for (int j = i; j < 5 && s >= coin[j]; j++)
		dp[s][i] += solve(j, s - coin[j]);
	return dp[s][i];
}

int main() {
	memset(dp, -1, sizeof(dp));
	for (int i = 0; i < 5; i++)
		dp[0][i] = 1;
	while (scanf("%d", &n) != EOF)
		printf("%lld\n", solve(0, n));
	return 0;
}


 

递推:自底向上的方法,需要注意的是1+5和5+1是一种的,所以要处理一下,从小往大排就不会错了。

代码:

 

/*
*  Author:      illuz <iilluzen[at]gmail.com>
*  Blog:        http://blog.csdn.net/hcbbt
*  File:        uva674.cpp
*  Create Date: 2013-09-20 13:48:56
*  Descripton:  dp, low to up
*/

#include <cstdio>
const int MAXN = 8000;
int n, coin[5] = {1, 5, 10, 25, 50};
long long dp[MAXN] = {1};

int main() {
	for (int i = 0; i < 5; i++)
		for (int j = 0; j < MAXN - 100; j++)
			dp[j + coin[i]] += dp[j];

	while (scanf("%d", &n) != EOF)
		printf("%lld\n", dp[n]);
	return 0;
}


 

 

posted on 2013-09-21 13:08  you Richer  阅读(250)  评论(0编辑  收藏  举报