acwing--动态规划【线性dp】4/20、4/21
1、数字三角形898. 数字三角形 - AcWing题库
涉及i-1一般初始化从1开始
考虑最后一行的数据:f[i][j] = max( f[i-1][j]右上角,f[i-1][j-1]左上角)
注意:1、#include<climits>可以定位INT_MAX,不过还可以用1e9,避免INT_MAX+1溢出
2、思考f[i][j]初始化为什么,求max的时候一般是-1e9,背包初始化为0是因为没负数,这里要考虑负数
#include<iostream>
#include<algorithm>
#include<climits>
using namespace std;
int main(){int n;//层数cin>>n;vector<vector<int>>v(n+1,vector<int>(n+1));
// 5
// 7
// 3 8
// 8 1 0
// 2 7 4 4
// 4 5 2 6 5//f[j] = max(f[j],f[j-1])+v[i][j]vector<int>f(n+1,-INT_MAX);//−10000≤三角形中的整数≤10000// int f[n];//输出32575for(int i = 1;i<=n;i++){for(int j = 1;j<=i;j++){//<=icin>>v[i][j];}}f[1] = v[1][1];if(n == 1){cout<<f[1];return 0;}for(int i = 2;i<=n;i++){for(int j = i;j>=1;j--){f[j] = max(f[j],f[j-1])+v[i][j];}}int max= -INT_MAX;for(int i = 1;i<=n;i++){if(f[i]>max){max = f[i];}}cout<<max;
}
2.最长上升子序列
895. 最长上升子序列 - AcWing题库
问题://最后一步的问题,不一定是f[n-1]max
如果想输出最长子序列,可以记录每一个元素的前一个标号
// 第一行包含整数 N
// 第二行包含 N个整数,表示完整序列。
#include<iostream>
#include<algorithm>
using namespace std;
int main(){//最长单调序列长度int n;cin>>n;vector<int>s(n);for(int i = 0;i<n;i++){cin>>s[i];}//f[i]:s[i]last的max长度//f[i] = max(f[i],f[k]+1)(k<i && s[k]<s[i])vector<int>f(n,1);for(int i = 0;i<n;i++){for(int j = 0;j<i;j++){if( s[j]<s[i]){f[i] = max(f[i],f[j]+1);}}}//最后一步的问题,不一定是f[n-1]maxint max = 0;for(int i = 0;i<n;i++){if(f[i]>max){max = f[i];}}cout<<max;
}
3最长公共子序列
求既是 A的子序列又是 B 的子序列的字符串长度最长是多少。
卡住咯
f[i][j]:第一个序列的前i个字母和第2个序列的前j个字母组成的公共子序列max长度
f[i][j] = ?【求递推公式其实也是在不重【求max的时候f递推式划分的子集可以重复,】不漏划分集合】
考虑增加第i个字母和第j个字母f、公共子序列可能的变化和情况
公共子序列相比之前可能:不增加
f[i-1][j]公共子序列不一定是以B[j]结尾