假設咱們有面值爲1元、3元和5元的硬幣若干枚。怎樣用最少的硬幣湊夠11元?html
這是博客http://hawstein.com/posts/dp-novice-to-advanced.html上面的一個入門的小樣例。ios
動態規劃算法的核心是:每個子問題的狀態和狀態的轉移方程。算法
狀態是:dp[i] ,即湊夠i元最少需要的硬幣的個數數組
轉移方程是:dp[i] = min(dp[i-C1]+1,dp[i-C2]+1,dp[i-C3]+1,……,dp[i-Cj]+1])函數
即。每個狀態的值都是最小的那個。post
說明:經過遞歸函數dp_fun實現了對狀態數組dp的初始化
spa
#include<iostream> using namespace std; int coin[3] = {1,3,5}; int dp[12] ; int min(int a,int b) { return (a<b)? a:b; } void dp_fun(int i,int num) { if(i == 0) { dp[i] = 0; dp_fun(1,num); return; } else { int MIN = 9999; for(int j=0;j<3;j++) { if(i>=coin[j]) { MIN = min(dp[i-coin[j]]+1,MIN); } } dp[i] = MIN; if(i == num)return; else dp_fun(i+1,num); } } int main() { dp_fun(0,11); //表示要湊齊11元的硬幣 for(int i=0;i<12;i++) { cout<<"湊齊"<<i<<"元。至少需要"<<dp[i]<<"枚硬幣"<<endl; } return 0; }
湊齊0元。至少需要0枚硬幣
湊齊1元,至少需要1枚硬幣
湊齊2元,至少需要2枚硬幣
湊齊3元,至少需要1枚硬幣
湊齊4元,至少需要2枚硬幣
湊齊5元,至少需要1枚硬幣
湊齊6元。至少需要2枚硬幣
湊齊7元,至少需要3枚硬幣
湊齊8元,至少需要2枚硬幣
湊齊9元。至少需要3枚硬幣
湊齊10元,至少需要2枚硬幣
湊齊11元,至少需要3枚硬幣
code
上面的程序是用遞歸寫的。比較長,如下在寫一個用兩層循環的:htm
talk is cheap ,show me the code:blog
#include<iostream> using namespace std; int coin[3] = {1,3,5}; int dp[12] ; void dp_fun(int num) { dp[0] = 0; for(int i=1;i<=num;i++) { dp[i] = 9999; for(int j=0;coin[j]<=i&&j<3;j++) { if(dp[i-coin[j]]+1 < dp[i]) dp[i] = dp[i-coin[j]]+1; } } } int main() { dp_fun(11); //表示要湊齊11元的硬幣 for(int i=0;i<12;i++) { cout<<"湊齊"<<i<<"元,至少需要"<<dp[i]<<"枚硬幣"<<endl; } return 0; }