题目:
是否能用贪心?
不能用贪心算法?
动态规划算法思路:
例如:
钞票面值:coins=[1,2,5,7,10]
金额:14
dp[i],代表金额i的最优解(即最小使用张数)
数组dp[]中存储金额1至金额14的最优解(存储最少使用钞票的数量)
初始化:dp[]中coins对应的金额置1,
else dp[]金额置-1
金额1最优解:dp[1]=1
金额2最优解:dp[2]=1
金额3最优解:
1)3= 1+2 ,则dp[3]=1+dp[2] ( 一张1块 + 金额为2对应最优解)
2)3= 2+1, 则dp[3]=1+dp[1](一张2块 + 金额为1对应最优解)
所以,dp[3]=min(dp[2],dp[1])+1;
金额4最优解:
1)4=1+3, 则dp[4]=1+dp[3] ( 一张1块 + 金额为3对应最优解)
2)4=2+2, 则dp[4]=1+dp[2] ( 一张2块 + 金额为2对应最优解)
所以,dp[4]=min(dp[3],dp[2])+1;
金额5最优解:dp[5]=1
金额6最优解:
1)6=1+5 ,则dp[6]=1+dp[5] ( 一张1块 + 金额为5对应最优解)
2)6=2+3,则dp[6]=1+dp[3] ( 一张2块 + 金额为3对应最优解)
3)6=5+1,则dp[6]=1+dp[1] ( 一张5块 + 金额为1对应最优解)
所以,dp[4]=min(dp[5],dp[3],dp[1])+1
……
金额14最优解:
1)14=1+13则dp[14]=1+dp[13] ( 一张1块 + 金额为13对应最优解dp[14-coins[0])
2)14=2+12则dp[14]=1+dp[12] ( 一张2块 + 金额为12对应最优解dp[14-coins[1]])
3)14=5+9则dp[14]=1+dp[9] ( 一张5块 + 金额为9对应最优解dp[14-coins[2]])
4)14=7+7则dp[14]=1+dp[7] ( 一张7块 + 金额为7对应最优解dp[14-coins[3]])
5)14=10+4则dp[14]=1+dp[4] ( 一张10块 + 金额为4对应最优解dp[14-coins[4]])
所以,dp[4]=min(dp[10],dp[7],dp[5],dp[3],dp[1])+1
综上:
核心代码:
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int> dp;
for(int i=0;i<=amount;i++){//初始化dp数组
dp.push_back(-1); //最初所有金额的最优解均为-1
}
dp[0]=0 ; //金额0最优解0 //递推
for(int i=1;i<=amount;i++){//循环各个面值,找到dp[i]最优解
for(int j=0;j<coins.size();j++){
if( i-coins[j]>=0&&dp[i-coins[j]]!=-1){ //??与的前后位置不能调,OJ会报错
if(dp[i]==-1 || dp[i] > dp[i-coins[j]]+1 )
dp[i]=dp[i-coins[j]]+1;
}
}
}
return dp[amount];
}
};