這都是比較常見的基礎動態規劃的問題,遞歸自頂向下實現這裏就不說了。理論上網上都比較多,主要把簡單的代碼實現寫下來。最大連續子序列和,最長不下降子序列和最長公共子序列都是經過測試的代碼:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
int continuous(vector<int> arr){//最長連續子序列的和
vector<int> res(arr.size());
res[0]=arr[0];
for(int i=1;i<arr.size();i++)//狀態轉移方程res[i]=max(res[i-1]+arr[i],arr[i]);
res[i]=max(res[i-1]+arr[i],arr[i]);
//遍歷一遍res求出最大的值
int m=res[0];
for(int i=1;i<res.size();i++)
m=max(m,res[i]);
return m;
}
int LIS(vector<int> arr){//最長不遞減問題
vector<int> res(arr.size(),1);
//res[i]代表以i爲結尾的最長子序列
//狀態轉移方程:res[i]=max(res[i],res[j]+1);
for(int i=1;i<arr.size();i++){
for(int j=0;j<i;j++){
if(arr[i]>arr[j])
res[i]=max(res[i],res[j]+1);
}
}
int m=1;
for(int i=1;i<res.size();i++)
m=max(m,res[i]);
return m;
}
int LCS(string str1,string str2){//最長公共子序列長度
int m=str1.size(),n=str2.size();
vector<vector<int> > res(m+1,vector<int>(n+1,0));
for(int i=1;i<m+1;i++){
for(int j=1;j<n+1;j++){
if(str1[i-1]==str2[j-1])//字符串要從下標爲0開始
res[i][j]=res[i-1][j-1]+1;
else
res[i][j]=max(res[i-1][j],res[i][j-1]);
}
}
return res[m][n];
}
int main(){
int test1[]={-2,11,-4,13,-5,-2};
vector<int> a(test1,test1+6);
cout<<"最長連續子序列的和爲:"<<continuous(a)<<endl;
int test2[]={12,10,3,-1,-2,7,9};
vector<int> b(test2,test2+7);
cout<<"最長不下降子序列長度爲:"<<LIS(b)<<endl;
string s2="sadstory",s1="adminsorry";
cout<<s1<<"和"<<s2<<"最長公共子序列長度爲:"<<LCS(s1,s2)<<endl;
return 0;
}