動態規劃總結

1. 518. 零錢兌換 II

給定不同面額的硬幣和一個總金額。寫出函數來計算可以湊成總金額的硬幣組合數。假設每一種面額的硬幣有無限個。 

輸入: amount = 5, coins = [1, 2, 5]
輸出: 4
解釋: 有四種方式可以湊成總金額:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

暴力遞歸  

索引index和cursum作爲可變參數,參與暴力遞歸

//暴力遞歸
 class solution {
 public:
     int change(int amount, vector<int>& coins) {
         if(amount<0)
             return 0;
         return p1(coins,0,amount);
     }
     int p1(vector<int>& coins,int index,int amount)// 不斷減少amout
     {// 當前情況下返回的個數
         int res=0;
         if(index == coins.size())//最後一個了
             return amount==0?1:0;
         // 暴力,當前的位置選了幾次
         for(int i=0;coins[index]*i <= amount;i++){
            res+=p1(coins,index+1,amount-coins[index]*i);
            return res;}
     }
 };

記憶化搜索(函數外加個傻緩存)

  1.  由可變參數構成一個結構(2個就是一個矩陣)(初始化,在遞歸函數之外)
  2.  get 操作,看此次可變參數對應的位置,之前出現過沒
  3.  put 操作,將運算得到的此次可變參數,對應的res弄給矩陣
class Solution {
public:
    int change(int amount, vector<int>& coins) {
         if(amount<0)
             return 0;
         vector<vector<int> > temp(coins.size()+1,vector<int>(amount+1,0));
         return p1(coins,0,amount,temp);
     }
     int p1(vector<int>& coins,int index,int amount,vector<vector<int> >& temp)
     {
         int res=0;
         if(index == coins.size())
             res= amount==0?1:0;
         else
         {
             int tempval=0;
             for(int i=0;coins[index]*i<=amount;i++)
             {
                 tempval=temp[index+1][amount-coins[index]*i];
                 // get 操作,get出來看之前是不是已經算出來了
                 if(tempval!=0)
                     res+= tempval==-1?0:tempval;
                 else
                     res+= p1(coins,index+1,amount-coins[index]*i,temp);
             }
         }
         // put操作,將這次計算的res放到,由可變形參組成的矩陣裏面。
         temp[index][amount]= res==0?-1:res;
         return res;
     }
};

動態規劃

class Solution {
public:
	int change(int amount, vector<int>& coins) {
		if (amount < 0 || (coins.size() == 0 && amount != 0))
			return 0;
		if (coins.size() == 0 && amount == 0)
			return 1;
		vector<vector<int> > dp(coins.size(), vector<int>(amount + 1, 0));
		for (int i = 0; i < coins.size(); ++i)
			dp[i][0] = 1;
		for (int i = 0; i < amount + 1; i++)
		{
			if (i%coins[0] == 0)
				dp[0][i] = 1;
			else
				dp[0][i] = 0;
		}
		for (int i = 1; i < coins.size(); ++i)
		{
			for (int j = 1; j < amount + 1; ++j)
			{
				// for(int k=0;k*coins[i]<=j;k++)//動態規劃
				// {
				//     dp[i][j]+=dp[i-1][j-k*coins[i]];
				// }
				if (coins[i] <= j) //動態規劃改進
					dp[i][j] = dp[i - 1][j] + dp[i][j - coins[i]];
				else
					dp[i][j] = dp[i - 1][j];
			}
		}
		return dp[coins.size() - 1][amount];
	}
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章