poj2479 Maximum sum (dp)
题意:k组数据,每组开始一个n代表n个数字,要求这些数字中不连续不重合不相交的两个子串和的最大值、
思路:显然是一个dp,对两端进行dp,找到以i为结尾的子串和的最大值和以i为开头的子串和的最大值,然后再开个数组rmx存储i及其之后的子串和的最大值,再i到n用i结尾的子串和的最大值和rmx相加找最大值即可。最大连续子串和的变式,还是蛮经典的,虽然不难(=。=)
AC代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<map>
#include<math.h>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#define INF 0x3F3F3F3F
#define endl '\n'
#define pb push_back
#define css(n) cout<<setiosflags(ios::fixed)<<setprecision(n);
#define sd(a) scanf("%d",&a)
#define sld(a) scanf("%lld",&a)
#define m(a,b) memset(a,b,sizeof a)
#define p_queue priority_queue
using namespace std;
typedef long long ll;
const int maxn=50005;
int n,m;
int t;
double a,b;
int arr[maxn];
int dp1[maxn]; //dp1[i]是以i为结尾的最大子串和
int dp2[maxn];//dp2[i]是以i为开头的最大子串和
int rmx[maxn];//rmx[i]是i以后的最长连续子串和
int main()
{
sd(t);
while(t--)
{
m(dp1,0);
m(dp2,0);
m(arr,0);
m(rmx,0);
sd(n);
for(int i=1;i<=n;i++)
{
scanf("%d",&arr[i]);
}
dp1[1]=arr[1];
dp2[n]=arr[n];
for(int i=2;i<=n;i++)
{
dp1[i]=max(dp1[i-1]+arr[i],arr[i]);
}
for(int i=n-1;i>=1;i--)
{
dp2[i]=max(dp2[i+1]+arr[i],arr[i]);
}
// int mx=0;
rmx[n]=dp2[n];
for(int i=n-1;i>=1;i--)
{
rmx[i]=max(rmx[i+1],dp2[i]);
}
int mx=-INF;//dp中的mx一定要初始化为负数。
for(int i=2;i<=n;i++)
{
mx=max(dp1[i-1]+rmx[i],mx);//两者不可以重合,所以是i-1和i
}
printf("%d\n",mx);
}
return 0;
}