動態規劃複習

問題1:ios

斐波拉契數列:ide

 

 

問題2:函數

爬樓梯:spa

一次只能走1或者2層臺階,給一個n層的樓梯,問,有多少種走法?3d

分析:code

    if(n==0)//null
        return 1;
    if(n==1)//1
        return 1;
    if(n==2)//11 2
        return 2;
    if(n==3)//111 12 21
        return 3;
    if(n==4)//1111 121 211 112 22 = 11+2 2+2 111+1 12+1 21+1 = f(2)+f(3)
        return 5;
    if(n==5)//11111 1112 1121 1211 2111 221 212 122
        //1111+1 121+1 211+1 112+1 22+1 <---4的基礎上再走 1 階
        //111+2 12+2 21+2    <---3的基礎上再走 2 階
        return 8;//f(3)+f(4)

規律由上可見:blog

f(n) = f(n-2)+f(n-1),變成了斐波拉契數列的遞推公式,因此實現代碼就和斐波拉契數列同樣了ci

 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 int dp[100];
 6 
 7 int f(int n){
 8     for(int i = 2;i<=n;i++)
 9         dp[i] = dp[i-1]+dp[i-2];//dp[i]表示第i層有多少種走法
10 
11 return dp[n];
12 
13 }
14 
15 
16 int main(){
17  int n;
18  cin >> n;
19  dp[0] = dp[1] =1;
20  cout << f(n)<<endl;
21  for(int i = 1;i<=n;i++)
22     cout << dp[i]<<" ";
23  cout<<endl;
24 return 0;
25 }
View Code

 問題3:leetcode

生兔子問題(可愛的小兔兔)string

規律分析:

 

第一年 1 = 1
第二年 1+1 = 2
第三年 (1+1)+ 1 = 3
第四年 (1+1+1)+ 1 = 4
第五年 (1+1+1+1)+(1+1) = 6 第一隻出生的小兔子也開始生寶寶啦
第六年 (1+(1+1)+1+1+1)+(1+1+1) = 9 = 6+3第二隻小兔子也開始生啦 同時第一隻小兔子又生了一個
第七年 (1+(1+1+1)+(1+1)+1+1+1)+(1+1+1+1)= 13 = 9+4
第八年 (1+(1+1+1+1)+(1+1+1)+(1+1)+1+1+1)+(1+(1+1)+1+1+1) = 19 = 13+6
發現,從第四年開始,每一年都是f[n] = f[n-1]+f[n-3]//緣由是小兔子要三年才能成熟

 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 /*
 6 設成熟的兔子每一年生1只兔子,而且永遠不會死
 7 第一年有1只成熟的兔子,從第二年開始,開始生兔子,
 8 每隻小兔子3年以後成熟又能夠繼續生。
 9 給出整數N,求出N年後兔子的數量
10 */
11 int res[100];
12 int f(int n){
13     if(n<=4)return n;
14     for(int i = 0;i<=4;i++)
15         res[i]=i;
16     for(int i = 5;i<=n;i++)
17         res[i] = res[i-1]+res[i-3];
18     return res[n];
19 }
20 int main(){
21     int n;
22     cin >> n;
23     cout << f(n) << endl;
24     for(int i = 1;i<=n;i++){
25         cout << res[i]<<" ";
26     }
27     cout << endl;
28 return 0;
29 }
View Code

 問題4

 

問題5

最小矩陣問題:

給定一個矩陣,值爲權重,從左上角到右下角,記錄權值總和最小的一條路徑的最小值

 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 
 6 int main(){
 7 
 8 int m,n;
 9 cin >> m >> n;
10 int map[m][n];
11 for(int i = 0;i<m;i++){
12     for(int j = 0;j<n;j++){
13         cin >> map[i][j];
14     }
15 }
16 
17 
18 /*
19 3 3
20 1 2 3
21 4 5 6
22 7 8 9
23 */
24 int dp[m][n];
25 dp[0][0] = map[0][0];
26 for(int i = 1;i<m;i++)
27     dp[i][0] = dp[i-1][0]+map[i][0];
28 for(int i = 1;i<n;i++)
29     dp[0][i] = dp[0][i-1]+map[0][i];
30 for(int i = 1;i<m;i++){
31     for(int j = 1;j<n;j++){
32         dp[i][j] = min(dp[i-1][j],dp[i][j-1])+map[i][j];
33     }
34 
35 }
36 cout <<dp[m-1][n-1];
37 return 0;
38 }
View Code

問題6 最長遞增子序列問題

 1 #include<vector>
 2 #include<iostream>
 3 #include<string>
 4 using namespace std;
 5 
 6 int lengthOfLIS(vector<int>& nums) {
 7     int ans = 0;
 8     int n = nums.size();
 9     int dp[n+1] = {0};
10     for(int i = 0;i<n;i++){
11         dp[i] = 1;
12     }
13     for(int i = 1;i<n;i++)
14         for(int j = 0;j<i;j++)
15             if(nums[i]>nums[j] && dp[j]+1>=dp[i])
16                 dp[i] = dp[j]+1;
17     for(int i = 0;i<n;i++)
18         ans = max(ans,dp[i]);
19     return ans;
20 }
21 
22 int main(){
23     /*
24 10
25 1 5 2 6 7 8 4 9 10 3
26 //1 5 6 7 8 9 10
27 //1 2 6 7 8 9 10
28 //7
29 5
30 1 3 2 3 3
31 //123
32 //3
33 9
34 3 6 9 3 3 3 8 6 3
35 //3 6 9
36 //3
37     */
38     int x,n;
39     cin >> n;
40     vector<int> m;
41     for(int i = 1;i<=n;i++){
42         cin >> x;
43         m.push_back(x);
44     }
45     cout << lengthOfLIS(m)<<endl;
46 
47 return 0;
48 }
View Code

 問題7 零錢問題

給定不一樣面額的硬幣 coins 和一個總金額 amount。編寫一個函數來計算能夠湊成總金額所需的最少的硬幣個數。若是沒有任何一種硬幣組合能組成總金額,返回 -1。

示例 1:

輸入: coins = [1, 2, 5], amount = 11
輸出: 3
解釋: 11 = 5 + 5 + 1
示例 2:

輸入: coins = [2], amount = 3
輸出: -1

來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/coin-change

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 int main(){
 7     vector<int> coins;
 8     int n,x;
 9     cin >> n;
10     for(int i = 0;i<n;i++)
11        {
12            cin >> x;
13            coins.push_back(x);
14        }
15     int amount;
16     cin >> amount;
17     int dp[amount+1];
18     int max_ = amount+1;
19     for(int i =0;i<amount;i++)
20         dp[i] = max_;
21     dp[0] = 0;
22     for(int i =1;i<= amount;i++)
23     for(int j = 0;j<n;j++){
24         if(coins[j] <= i)
25             dp[i] = min(dp[i],dp[i-coins[j]]+1);
26     }
27     cout << (dp[amount] > amount?-1:dp[amount]);
28 
29 
30 return 0;
31 }
View Code
相關文章
相關標籤/搜索