zoukankan      html  css  js  c++  java
  • 动态规划解题(leetcode322零钱兑换)

    动态规划问题的一般形式就是求最值。最显著的特点是最优子结构和重叠子问题。最优子结构就是子问题的最优解,可以从子问题的最优结果推出更大规模问题的最优结果,可以用状态转移方程描述问题。重叠子问题可以通过创建备忘录dp[]避免重复计算。
    零钱兑换的解题步骤:
    1)先确定状态,也就是原问题和子问题中变化的变量,由于硬币数量可以无限,所以唯一确定的状态就是目标金额amount。
    2)然后确定dp函数的定义,当前的目标金额是n,至少需要dp(n)个硬币凑出该金额。
    3)确定选择并择优,无论当前的目标金额是多少,选择就是从面额列表coins中选则一个硬币,然后目标金额就会减少。
    4)最后明确递归的终止条件,显然目标金额为0时,所需硬币数量为0,而当目标金额小于0时,无解。在动态规划中体现为子问题无解,跳过该次内层循环。
    凑零钱问题的状态转移方程如下:

    [dp(n)=egin{cases} 0 & n=0 \ -1 & n<0 \ min{dp[n-coin]+1 | coinin coins} & n>0 end{cases}]

    int coinChange(vector<int>& coins, int amount) {
            vector<int> dp(amount+1, amount+1);
            dp[0] = 0;
            for(int i = 0; i < dp.size(); i++)
            {
                for(int coin : coins)
                {
                    if(i-coin < 0)
                        continue;
                    dp[i] = min(dp[i], 1+dp[i-coin]);//索引为i-coin的dp[i-coin]加上for循环在这次选出的这个coin(即加1)
    
                }
            }
            return dp[amount] == amount+1 ? -1 : dp[amount];//为什么要这样返回??当给的coins不能凑出amount时就会出错,比如coins=[2],amount=3,amount无法凑出,此时应返回-1
        }
    
  • 相关阅读:
    常用函数集锦
    HDU1212加深下对取模运算的理解
    HDU1022 queue和vector模拟
    设计模式原则
    3.6html学习笔记之样式选择
    poj 1274(二分图最大匹配)
    poj 1469(二分图最大匹配)
    poj 3692(二分图匹配--最大独立集)
    Codeforces Round #230 (Div. 1) 解题报告
    Codeforces Rockethon 2014 解题报告
  • 原文地址:https://www.cnblogs.com/jiangzhongzhiwei/p/13252017.html
Copyright © 2011-2022 走看看