两个基本题,求和最大的子数组和最长公共子串,应该熟练掌握这两种类型的动态规划最优解
代码如下:
Common Subsequence
#include <cstdio>
#include <string>
#include <sstream>
#include <iostream>
#include <cstring>
using namespace std;
#define max_length 1000
int result[max_length][max_length];
string str1,str2;
int main()
{
string str;
while(getline(cin,str) && (str != "")){
memset(result,0,sizeof(result));
stringstream data; //用字符串流获得两个单词,比较方便
data.str(str);
data>>str1>>str2;
int str1_length = str1.length();
int str2_length = str2.length();
for(int j=1;j<=str1_length;j++)
for(int n=1;n<=str2_length;n++){
if(str1[j-1] == str2[n-1])
result[j][n] = result[j-1][n-1]+1;
else
result[j][n] = max(result[j-1][n],result[j][n-1]);
}
cout<<result[str1_length][str2_length]<<endl;
}
return 1;
}
Maximum sum
#include <iostream> #include <cstdio> #include <string> using namespace std; #define maxn 50000+10 int data[maxn]; int main() { int cases; scanf("%d",&cases); while(cases--){ string str; getline(cin,str); int numbers; scanf("%d",&numbers); for(int i=1;i<=numbers;i++) scanf("%d",&data[i]); int dp_left[maxn],dp_right[maxn]; dp_left[1] = data[1] ,dp_right[numbers] = data[numbers]; for(int j=2;j<=numbers;j++){ if(dp_left[j-1]>0) dp_left[j] = dp_left[j-1]+data[j]; else dp_left[j] = data[j]; } for(int j=2;j<=numbers;j++) if(dp_left[j]<dp_left[j-1]) dp_left[j] = dp_left[j-1]; for(int j=numbers-1;j>=1;j--){ if(dp_right[j+1]>0) dp_right[j] = dp_right[j+1]+data[j]; else dp_right[j] = data[j]; } for(int j=numbers;j>1;j--) if(dp_right[j]>dp_right[j-1]) dp_right[j-1] = dp_right[j]; int max = -(1<<20); for(int j=1;j<numbers;j++) max = (dp_left[j] + dp_right[j+1] > max ? dp_left[j] + dp_right[j+1] : max); cout<<max<<endl; } return 0; }