• 线性dp


    一:数字三角形

    给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。

            7
          3   8
        8   1   0
      2   7   4   4
    4   5   2   6   5
    

    输入格式

    第一行包含整数n,表示数字三角形的层数。

    接下来n行,每行包含若干整数,其中第 i 行表示数字三角形第 i 层包含的整数。

    输出格式

    输出一个整数,表示最大的路径数字和。

    数据范围

    1n5001≤n≤500,
    1000010000−10000≤三角形中的整数≤10000

    输入样例:

    5
    7
    3 8
    8 1 0 
    2 7 4 4
    4 5 2 6 5
    

    输出样例:

    30


     1 #include <iostream>
     2 using namespace std;
     3 
     4 const int N = 510;
     5 const int INF = 0x3f3f3f3;
     6 
     7 int map[N][N], dp[N][N];
     8 int n;
     9 
    10 int main(){
    11     cin >> n;    
    12     for(int i = 1;i <= n;++i) 
    13         for(int j = 1;j <= i;++j)
    14             cin >> map[i][j];
    15     
    16     for(int i = 0;i <= n;++i)
    17         for(int j = 0;j <= i+1;++j)
    18             dp[i][j] = -INF;
    19     
    20     dp[1][1] = map[1][1];
    21     for(int i = 2;i <= n;++i)
    22         for(int j = 1;j <= i;++j)
    23             dp[i][j] = max(dp[i-1][j-1]+map[i][j], dp[i-1][j]+map[i][j]); 
    24     
    25     int res = 0;
    26     for(int i = 1;i <= n;++i) res = max(res, dp[n][i]);
    27     cout << res << endl;
    28     return 0;
    29 }
    View Code

    二:最长上升子序列

    给定一个长度为N的数列,求数值严格单调递增的子序列的长度最长是多少。

    输入格式

    第一行包含整数N。

    第二行包含N个整数,表示完整序列。

    输出格式

    输出一个整数,表示最大长度。

    数据范围

    1N10001≤N≤1000,
    109109−109≤数列中的数≤109

    输入样例:

    7
    3 1 2 1 8 5 6
    

    输出样例:

    4

     1 #include <iostream>
     2 using namespace std;
     3 
     4 const int N = 1000;
     5 int arr[N];
     6 int dp[N];
     7 
     8 int main(){
     9     int n; cin >> n;
    10     for(int i = 0;i < n;++i) cin >> arr[i];
    11     
    12     for(int i = 0;i < n;++i){
    13         dp[i] = 1;
    14         for(int j = 0;j < i;++j)
    15             if(arr[j] < arr[i])
    16                 dp[i] = max(dp[i], dp[j]+1);
    17     }
    18     int res = 0;
    19     for(int i = 0;i < n;++i) res = max(res, dp[i]);
    20     cout << res << endl;
    21     return 0;
    22 }
    View Code

    三:最长公共子序列

    给定两个长度分别为N和M的字符串A和B,求既是A的子序列又是B的子序列的字符串长度最长是多少。

    输入格式

    第一行包含两个整数N和M。

    第二行包含一个长度为N的字符串,表示字符串A。

    第三行包含一个长度为M的字符串,表示字符串B。

    字符串均由小写字母构成。

    输出格式

    输出一个整数,表示最大长度。

    数据范围

    1N10001≤N≤1000,

    输入样例:

    4 5
    acbd
    abedc
    

    输出样例:

    3


     1 #include <iostream>
     2 using namespace std;
     3 
     4 const int N = 1010;
     5 
     6 char a[N], b[N];
     7 int dp[N][N];
     8 
     9 int main(){
    10     int n, m;cin >> n >> m;
    11     cin >> a+1;cin >> b+1;
    12     for(int i = 1;i <= n;++i)   
    13         for(int j = 1;j <= m;++j)
    14             if(a[i] == b[j])
    15                 dp[i][j] = dp[i-1][j-1] + 1;
    16             else 
    17                 dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
    18     
    19     cout << dp[n][m] << endl;
    20     return 0;
    21 }
    View Code

    四:最短编辑距离

    给定两个字符串A和B,现在要将A经过若干操作变为B,可进行的操作有:

    1. 删除–将字符串A中的某个字符删除。
    2. 插入–在字符串A的某个位置插入某个字符。
    3. 替换–将字符串A中的某个字符替换为另一个字符。

    现在请你求出,将A变为B至少需要进行多少次操作。

    输入格式

    第一行包含整数n,表示字符串A的长度。

    第二行包含一个长度为n的字符串A。

    第三行包含整数m,表示字符串B的长度。

    第四行包含一个长度为m的字符串B。

    字符串中均只包含大写字母。

    输出格式

    输出一个整数,表示最少操作次数。

    数据范围

    1n,m10001≤n,m≤1000

    输入样例:

    10 
    AGTCTGACGC
    11 
    AGTAAGTAGGC
    

    输出样例:

    4

     1 #include <iostream>
     2 using namespace std;
     3 
     4 const int N = 1010;
     5 
     6 char a[N], b[N];
     7 int dp[N][N]; //表示从1到i 和 1到j 匹配的最小操作次数
     8 
     9 int main(){
    10     int n = 0;cin >> n;
    11     cin >> a+1;
    12     int m = 0;cin >> m;
    13     cin >> b+1;
    14     
    15     for(int i = 0;i <= m;++i) dp[0][i] = i;
    16     for(int i = 0;i <= n;++i) dp[i][0] = i;
    17     
    18     for(int i = 1;i <= n;++i)
    19         for(int j = 1;j <= m;++j){
    20             dp[i][j] = min(dp[i][j-1] + 1, dp[i-1][j] + 1);//插入和替换
    21             if(a[i] == b[j])
    22                 dp[i][j] = min(dp[i][j], dp[i-1][j-1]);
    23             else 
    24                 dp[i][j] = min(dp[i][j], dp[i-1][j-1] + 1);
    25         }
    26     
    27     cout << dp[n][m] << endl;
    28     return 0;
    29 }
    View Code
  • 相关阅读:
    解决pyinstaller 打包后运行exe程序出现的"ModuleNotFindError"
    【Tensorflow专题-03】深层神经网络
    【Tensorflow专题-02】使用tensorflow训练神经网络
    【Tensorflow专题-01】深度学习应用介绍及tensorflow基本使用
    Github 简明教程
    Composer 安装与使用
    为jQuery的$.ajax设置超时时间
    thinkphp 数据库表多字段排序
    TP5如何隐藏入口文件index.php
    Atom编辑器快捷键大全
  • 原文地址:https://www.cnblogs.com/sxq-study/p/12303589.html
Copyright © 2020-2023  润新知