线性dp
1数字三角形
#include <bits/stdc++.h>
using namespace std;
const int N=510,INF=1e9;//取一个无穷大是为了方便比较和获取最值
int a[N][N];
int f[N][N];
int n;
int main()
{
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++)
for(int j=0;j<=i+1;j++)
f[i][j]=-INF;
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-1]+a[i][j],f[i-1][j]+a[i][j]);
int res=-INF;
for(int i=1;i<=n;i++)
res=max(res,f[n][i]);
cout<<res;
return 0;
}
2最长上升子序列
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N];
int a[N];
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
{
f[i]=1;
for(int j=1;j<i;j++)
if(a[j]<a[i])
f[i]=max(f[i],f[j]+1);
}
int res=0;
for(int i=1;i<=n;i++)
res=max(res,f[i]);
cout<<res;
return 0;
}
最长公共子序列
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
char a[N],b[N];
int f[N][N];
int main()
{
int n,m;
cin>>n>>m;
cin>>a+1>>b+1;
//cout<<a+1<<b+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(a[i]==b[j])
f[i][j]=max(f[i][j],f[i-1][j-1]+1);
}
cout<<f[n][m];
return 0;
}
最短编辑距离
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
char a[N],b[N];
int f[N][N];
int n,m;
int main()
{
cin>>n>>a+1;
cin>>m>>b+1;
for(int i=0;i<=m;i++)f[0][i]=i;//初始化
for(int i=0;i<=n;i++)f[i][0]=i;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
f[i][j]=min(f[i-1][j]+1,f[i][j-1]+1);//增删
if(a[i]==b[j])f[i][j]=min(f[i][j],f[i-1][j-1]);//改
else f[i][j]=min(f[i][j],f[i-1][j-1]+1);
}
cout<<f[n][m];
return 0;
}
最长上升子序列2
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
int q[N],a[N];//q[N]存上升子序列
int n;
int main()
{
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
int len=0;
q[0]=-2e9;
for(int i=0;i<n;i++)//二分找到a[i]前面的最大值
{
int l=0,r=len;
while(l<r)
{
int mid=l+r+1>>1;
if(q[mid]<a[i])//小于区间右移,大于的话重新更新存的上升子序列,并且r-1;
l=mid;
else r=mid-1;
}
len=max(len,r+1);//最长长度
q[r+1]=a[i];更新上升子序列
}
cout<<len;
return 0;
}