题意:求一段序列的最大两段子段和。
解法:dp。用pre数组记录以i结尾的上一次求的最大x段子段和,那么对于最大x+1段子段和,dp[i] = max(dp[i - 1], pre[i - 1]) + a[i],由dp[i - 1]转移来的表示在第x+1个子段的末尾再加一个数,由pre[i - 1]转移来的表示在x个子段的基础上新添加一个以a[i]开头的子段。
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; LL a[50005], pre[50005], dp[50005]; int main() { int T; while(~scanf("%d", &T)) { while(T--) { int n; LL ans; scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%lld", &a[i]); } memset(pre, 0, sizeof pre); for(int i = 0; i <= n; i++) dp[i] = INT_MIN; for(int i = 0; i < 2; i++) { ans = INT_MIN; for(int j = 1; j <= n; j++) { dp[j] = max(pre[j - 1] + a[j], dp[j - 1] + a[j]); pre[j - 1] = ans; ans = max(ans, dp[j]);//顺序很重要喵 } pre[n] = ans; } printf("%lld ", ans); } } return 0; }