UVa 674 - Coin Change 动态规划入门

/**
*  刚开始做dp题,不习惯啊。看人代码还理解了老半天。。
*  动态规划 入门题
*  一直在想dp[i][j]是什么意思。。其实为了避免重复的选取,也就是分钱。
*  目标num,可以按时间阶段选取,比如第一次选取coins[0](也就是1) 那总数num就应该减一,即num-coins[0]
*  这样循环下令j从0-4,也就是5种硬币都要选取,这样就不会遗漏也不会重复了。
*  所以dp[i][j]的具体含义就是,对i值的钱分配,用第j种硬币以后的可能分配方法数
*  dp的核心就是状态和状态转移方程。。
*  本题状态转移就是一开始的币值num 在经过5种选择之后会分别转移到 num-coins[i].
*/


#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
#include <string>
#include <queue>
#include <map>
#include <algorithm>
#define INF 0x7fffffff

using namespace std;
int dp[7500][5], coins[5] = {1, 5, 10, 25, 50};

int dfs(int num, int t) {
    if(dp[num][t] != -1)
        return dp[num][t];
    dp[num][t] = 0;
    /* 不是从i=0开始,避免重复! */
    for(int i = t; i < 5; i ++) {
        if(num >= coins[i])
            dp[num][t] += dfs(num - coins[i], i);
    }
    return dp[num][t];
}


int main()
{
    int num;
    /* 如果把这个初始化放while里会超时! 因为这样每次都初始化,就不能记录之前所计算的值了 */
    memset(dp, -1, sizeof(dp));
    for(int i = 0; i < 5; i++)
        dp[0][i] = 1;
    while(scanf("%d", &num) != EOF) {
        printf("%d\n", dfs(num, 0));
    }
    return 0;
}


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值