04 线性DP

数字三角形(也可以使用记忆化搜索来做)

原题链接 https://www.acwing.com/problem/content/900/

# 顺推
#include<bits/stdc++.h>

using namespace std;

const int N = 510;
const int INF = 0x3f3f3f3f;
int f[N][N];
int a[N][N];


int main()
{
    int n;
    cin>>n;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= i; j++)
            cin>>a[i][j];
    for (int i = 1; i <= n; i++) memset(f[i], -INF, sizeof(f[i]));
    f[1][1] = a[1][1];
    for (int i = 2; i <= n; i++){
        for (int j = 1; j <= i; j++) {
            f[i][j] = max(f[i - 1][j], f[i -1][j - 1]) + a[i][j];
        }
    }
    int ans = - INF;
    for (int i = 1; i <= n; i++) ans = max(ans, f[n][i]);
    cout<<ans<<endl;
    return 0;
}

最长上升子序列

原题链接 https://www.acwing.com/activity/content/problem/content/1003/
状态变量f[i]:记录以i为结尾的最长上升子序列长度

状态转移方程: a[i] > a[j] 则f[i] = max(f[i], f[j] + 1)

初始化f[i] = 1

#include<bits/stdc++.h>

using namespace std;

const int N = 1010;

int a[N], f[N];


int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) cin >>a[i];
    fill(f, f + n, 1);
    int ans = 1;
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (a[i] > a[j]) f[i] = max(f[i], f[j] + 1);
        }
        ans = max(f[i], ans);
    }
    cout << ans<<endl;
    return 0;
}

优化解法(dp + 二分)

最长不下降子序列

最长公共子串

最长公共子序列

原题链接 https://www.acwing.com/problem/content/899/

编辑距离

posted @ 2021-11-05 17:49  dacyuan  阅读(30)  评论(0编辑  收藏  举报