动态规划题讲解

动态规划题讲解

【问题描述】

 

写一个程序,从标准输入上读入一个正整数N(1 <= N <=1000),计算出N元人民币兑换成1分、2分和5分的硬币,有多少种可能的组合。将结果以整数的方式输出到标准输出上,占一行。

 

【输入形式】

 

正整数N。(1 <= N <=1000)

 

【输出形式】

 

整数。

 

【输入样例】

 

1

 

【输出样例】

 

541

 

【时间限制】

 

1s

 

【空间限制】

 

65536KB

#include<stdio.h>
#define maxrow 3
#define maxcol 500000
int dp[maxrow][maxcol];
//dp[x][y]表示前x种硬币凑出y元的方案数
//有递推式
//k = [y / v[x]](向下取整)
//dp[x][y] = dp[x - 1][y - v[x] * 0] + dp[x - 1][y - v[x] * 1] + ... + dp[x - 1][y - v[x] * k]
//该公式可以理解为
//使用前x种硬币的方案数=(使用一个第x硬币前提下,使用前x-1种硬币解决掉剩余钱的方案数)+<pre name="code" class="cpp">//(使用两个第x硬币前提下,使用前x-1种硬币解决掉剩余钱的方案数)+..............+<pre name="code" class="cpp">//(使用[y/v[x]]个第x硬币前提下,使用前x-1种硬币解决掉剩余钱的方案数)

 //而 
 
//when y>=v[x]
//dp[x][y - v[x]] = dp[x - 1][y - v[x] * 1] + ... + dp[x - 1][y - v[x] * k]
//= > dp[x][y] = dp[x - 1][y] + dp[x][y - v[x]];
//when y = v[x]
//dp[x][y] = dp[x - 1][y]+1
//= >dp[x][0] = 1(for x in [0,x])
//这里为了能够清楚的讲解动态规划的状态转移,选择空间复杂度为O(maxRow*maxCol)的做法,实际上可以优化为O(maxCol)
int main(){
	int money;
	int i;
	int j;
	int k;
	int v[3] = { 1, 2, 5 };
	scanf("%d", &money);
	money *= 100;
	for (i = 0; i <= money; ++i){
		dp[0][i] = 1;
	}
	for (i = 0; i < maxrow; ++i){
		dp[i][0] = 1;
	}
	dp[1][1] = 1;
	for (i = 1; i < maxrow;++i){
		for (j = v[i]; j <= money; ++j){
			if (j >= v[i]){
				dp[i][j] = dp[i - 1][j] + dp[i][j - v[i]];
			}
		}
		if (i < maxrow - 1){
			for (k = 1; k < v[i]; ++k){
				dp[i + 1][k] = dp[i][k];
			}
		}
	}
	printf("%d", dp[maxrow-1][money]);
	system("pause");
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值