在上次的博客中,我们研究了线性dp中很有名的问题——字符串编辑距离。
本期我们来看一下线性dp中的最大和问题。本期是第一期,还会有第二期。
最大子序列和
这是一个很著名的问题。问题是:对于给定序列,寻找它的连续的最大和子数组。
这很简单。你只需要比较一下a[i]和dp[i-1]+a[i]的大小就可以了。代码如下:
#include <bits/stdc++.h>
using namespace std;
int a[maxn],dp[maxn];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
int ans=-inf;
for(int i=2;i<=n;i++){
dp[i]=max(dp[i-1]+a[i],a[i]);
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
return 0;
}
数字三角形
这是另一个很简单的问题。问题是:给出一个数字三角形,现在要从左上角走到第 i 行第 j 列,每
一步只能走到相邻的结点,求经过的结点的最大数字和。
我们可以很轻松的得出状态转移方程:dp[i][j]=a[i][j]+max(dp[i-1][j],dp[i-1][j-1]);不懂的自己画个图就
行了。嗯,代码...应该就不用放了吧...
#include<bits/stdc++.h>
using namespace std;
int a[maxn][maxn],dp[maxn][maxn];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
cin>>a[i][j];
dp[i][j]=a[i][j];
}
}
for(int i=n-1;i>=1;i--){
for(int j=1;j<=i;j++)
dp[i][j]+=max(dp[i+1][j],dp[i+1][j+1]);
}
cout<<dp[1][1]<<endl;
return 0;
}
好了,以上就是本期内容了。我们下期再见ヾ( ̄▽ ̄)!