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/