日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

零钱兑换I

發(fā)布時(shí)間:2024/4/18 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 零钱兑换I 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

思路

題目中說每種硬幣的數(shù)量是無限的,可以看出是典型的完全背包問題。

確定dp數(shù)組以及下標(biāo)的含義

dp[ j ]:湊足總額為 j 所需錢幣的最少個(gè)數(shù)為 dp[ j ]

確定遞推公式

得到dp[j](考慮coins[i]),只有一個(gè)來源,dp[j - coins[i]](沒有考慮coins[i])。

湊足總額為j - coins[i]的最少個(gè)數(shù)為dp[j - coins[i]],那么只需要加上一個(gè)錢幣coins[i]即dp[j - coins[i]] + 1就是dp[j](考慮coins[i])

所以dp[j] 要取所有 dp[j - coins[i]] + 1 中最小的。

遞推公式:dp[j] = min(dp[j - coins[i]] + 1, dp[j]);

dp數(shù)組如何初始化

首先湊足總金額為0所需錢幣的個(gè)數(shù)一定是0,那么dp[0] = 0;

其他下標(biāo)對應(yīng)的數(shù)值呢?

考慮到遞推公式的特性,dp[j]必須初始化為一個(gè)最大的數(shù),否則就會在min(dp[j - coins[i]] + 1, dp[j])比較的過程中被初始值覆蓋。

所以下標(biāo)非0的元素都是應(yīng)該是最大值。

代碼如下:

vector<int> dp(amount + 1, INT_MAX); dp[0] = 0;

確定遍歷順序

本題求錢幣最小個(gè)數(shù),那么錢幣有順序和沒有順序都可以,都不影響錢幣的最小個(gè)數(shù)。

所以本題并不強(qiáng)調(diào)集合是組合還是排列。

如果求組合數(shù)就是外層for循環(huán)遍歷物品,內(nèi)層for遍歷背包。

如果求排列數(shù)就是外層for遍歷背包,內(nèi)層for循環(huán)遍歷物品。

在動(dòng)態(tài)規(guī)劃專題中求組合數(shù)是:518.零錢兌換II,求排列數(shù)是:377. 組合總和 Ⅳ。

所以本題的兩個(gè)for循環(huán)的關(guān)系是:外層for循環(huán)遍歷物品,內(nèi)層for遍歷背包或者外層for遍歷背包,內(nèi)層for循環(huán)遍歷物品都是可以的!

那么我采用coins放在外循環(huán),target在內(nèi)循環(huán)的方式。

本題錢幣數(shù)量可以無限使用,那么是完全背包。所以遍歷的內(nèi)循環(huán)是正序

綜上所述,遍歷順序?yàn)?#xff1a;coins(物品)放在外循環(huán),target(背包)在內(nèi)循環(huán)。且內(nèi)循環(huán)正序。

舉例推導(dǎo)dp數(shù)組

以輸入:coins = [1, 2, 5], amount = 5為例

class Solution { public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount+1,INT_MAX);dp[0]=0;for(int ii=0;ii<coins.size();ii++){// 遍歷物品for(int jj=coins[ii];jj<=amount;jj++){// 遍歷背包if(dp[jj-coins[ii]]!=INT_MAX) dp[jj]=min(dp[jj],dp[jj-coins[ii]]+1);// 如果dp[j - coins[i]]是初始值則跳過}}if(dp[amount]==INT_MAX) return -1;return dp[amount];} };

對于遍歷方式遍歷背包放在外循環(huán),遍歷物品放在內(nèi)循環(huán)也是可以的

class Solution { public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount+1,INT_MAX);dp[0]=0;for(int jj=0;jj<=amount;jj++){for(int ii=0;ii<coins.size();ii++){if(jj>=coins[ii]&&dp[jj-coins[ii]]!=INT_MAX) dp[jj]=min(dp[jj],dp[jj-coins[ii]]+1);}}if(dp[amount]==INT_MAX) return -1;return dp[amount];} };

總結(jié)

以上是生活随笔為你收集整理的零钱兑换I的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。