题目大意: 对于连续的整数和的串s1和s2,s1与s2不相交,使得s1+s2最大
解题方法: DP。
lt[i]代表以第i个元素结尾的串最大值
rt[i]代表以第i个元素开头的串的最大值
那么设置一个rtm[i]代表取后i个元素之中最大连续子串的和
很显然,lt[i]=max(a[i],lt[i-1]+a[i]);
rt[i]=max(a[i],rt[i+1]+a[i]);
rtm[i]=max(rtm[i+1],rt[i]);
此题与poj2593一模一样,但是要将MAXV改成10010就可以A了
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN = 100008;
int dp1[MAXN], dp2[MAXN], a[MAXN], dpp[MAXN];
int main() {
int n;
while (scanf("%d", &n) && n) {
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
dp1[i] = max(a[i], dp1[i-1]+a[i]);
}
dp2[n] = a[n];
for(int i = n-1; i > 0; i--)
dp2[i] = max(a[i], dp2[i+1]+a[i]);
dpp[n] = a[n];
for(int i = n-1; i > 0; i--)
dpp[i] = max(dp2[i], dpp[i+1]);
int result = -MAXN; //注意别习惯性初始化为0;
for(int i = 1; i < n; i++)
result = max(result, dp1[i]+dpp[i+1]);
cout<<result<<endl;
}
return 0;
}
思路二:
d[i][0]前i个以i结尾选了一段
d[i][1]前i个以i结尾选了两段
然后扫描维护一个d[i][0]的最大值mx,转移
d[i][0]=max(0,d[i-1][0])+a[i];
d[i][1]=max(d[i-1][1],mx)+a[i];
初始化注意一下就行了;
代码就不写了