題目描述:給定數量不限的硬幣,幣值為25分、10分、5分和1分,編寫**計算n分有幾種表示法。(結果可能會很大,你需要將結果模上1000000007)
示例1:
輸入: n = 5
輸出:2
解釋: 有兩種方式可以湊成總金額:
5=55=1+1+1+1+1
示例2:
輸入: n = 10
輸出:4
解釋: 有四種方式可以湊成總金額:
10=10
10=5+5
10=5+1+1+1+1+1
10=1+1+1+1+1+1+1+1+1+1
思路:看到這道題我們的第乙個想法就是將各個面額可組成n
的情況進行相加,但是要如何實現這個轉移方程呢?我們先看乙個例子n=10
當n=10時,有四種組合,我們看一下這四種組合
1個10
2個55個1,乙個5
10個1
我們從觀察一下,發現使用較大面額的硬幣是在遞減的,一開始是使用乙個面額為10的,後來就是使用兩個面額為5,再使用乙個面額為5,再下去就是全部都用面額為1的
我們寫乙個簡單的狀態轉移方程:
f(10) = f(5,10)+f(5,0)
f(5,10) = f(1,10)+f(1,5)+f(1,0)
發現沒有,f(5,10)–>f(5,0)就是乙個有沒有使用10面額的差別,如果使用了10面額,那麼我們需要用5合層的就是f(5,10-10)
從上面我們可以得到完整的狀態轉移方程,用i表示第幾種面額的硬幣,v表示n,c表示第i種硬幣的面額:
f(i,v) = f(i-1,v)+f(i-1,v-c)+f(i-1,v-2c)+...+f(i-1,v-kc)
v-kv>=0
上面的方程還能再簡化為:
f(i,v) = f(i-1,v)+f(i,v-c)
因為我們需要用到的只是i-1即類似這樣的資料f(i,v) = f(i-1,v)+f(i-1,v-c)+f(i-1,v-2c)+...+f(i-1,v-kc)
,所以我們用乙個一維陣列f來儲存這些資料
for(i=coin; i<=n; i++)
f[i]=(f[i]+f[i-coin])%mod;
有沒有覺得f[i]=(f[i]+f[i-coin])
這段**很熟悉,其實這段**就對應了前面的狀態轉移方程f(i,v) = f(i-1,v)+f(i,v-c)
,只是因為f(i)儲存的其實是f[i-1]的值,這一步就是將其更新
完整**:
感覺動態規劃還是很難啊,這道題想了挺久的,就覺得跟前面的題一樣,很難想出乙個很正確的轉移方程,這道題之前也做過類似的,揹包問題,動態轉移方程是一樣的,打算寫完這篇部落格去看一下《揹包九講》,希望能夠體會乙個動態規劃的精髓
高頻演算法面試題學習總結 動態規劃3 換硬幣
題目 硬幣很多種,價值各 同。拼成乙個數。最少用幾個?輸入 coins target 10 輸出 3 解釋 最少使用的硬幣數是3 包含兩個4和乙個2 思路分析 1.貪心法 從最大硬幣值開始,逐步往低試。反例 coins target 20 應輸出 4 4 5 貪心法輸出 6 11 5 4 1 貪心法...
面試題 08 11 硬幣
硬幣。給定數量不限的硬幣,幣值為25分 10分 5分和1分,編寫 計算n分有幾種表示法。結果可能會很大,你需要將結果模上1000000007 示例1 輸入 n 5 輸出 2 解釋 有兩種方式可以湊成總金額 5 55 1 1 1 1 1 示例2 輸入 n 10 輸出 4 解釋 有四種方式可以湊成總金額...
硬幣找零問題,動態規劃基礎,百度面試題
問題描述 給出幾種面值的硬幣,要求用這幾種硬幣找零出所給零錢數,用的硬幣數要最少。那麼動態規劃又該如何解決,動態規劃在於在解決問題的途中用到之前的得到的答案。如下 includeusing namespace std 三個引數依次是硬幣面值陣列,硬幣種類,給出的零錢 void getmin int ...