动态规划复习

问题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
相关文章
相关标签/搜索