leetcode[面试题 08.11. 硬币]

leetcode面试题 08.11. 硬币

思路参考这位大兄弟

第一眼看这题就能感觉到用dp去写,题目问我们n分有多少种表示法,我们像如果我们把最后一个硬币的面值j给定,那么题目就转化成求n-j分有多少表示法,这样就转化为了子问题。

刚开始我想是用面值去定硬币方案数,其转移方程是dp[i] = (dp[i-1]+dp[i-5]+dp[i-10]+dp[i-25]) dp[i] 表示i分的表示方案数,但这样写是不对的,比如6,如果按照转移方程dp[6] = dp[5]+dp[1] = 3,但实际的答案是2,因为实际上的6是由5 1 和 1 1 1 1 1 1两种情况组成,但如果按照dp转移方程去写的话:6是由5 1和 1 5 和1 1 1 1 1 1 组成,我们发现数重了,那这样写就肯定不对了

方法:我们选择用硬币去定面值,那这样的最终结果中的每个排序肯定是不下降的,就能做到不重

const int maxn = 1e6+50;
const int MOD = 1e9+7;
int dp[maxn];
class Solution {
public:
    int num[4] = {1,5,10,25}; 
    int waysToChange(int n) {
        memset(dp,0,sizeof(dp));
        dp[0] = 1;
        for(int i = 0; i < 4; i++){
            for(int j = 1; j <= n; j++){
                if(j >= num[i]) dp[j] = (dp[j]+dp[j-num[i]])%MOD;
            }
        }
        return dp[n];
    }
};

总结:在写动态规划的时候,当发现我们的思路不对或者说不完全对的时候,我们要做的不是去补原思路的漏洞,而是应该换个方向去想问题

猜你喜欢

转载自www.cnblogs.com/Beic233/p/12760370.html