Two Subarrays Gym

来源:互联网 发布:神回复知乎 编辑:程序博客网 时间:2024/06/07 00:58

http://codeforces.com/gym/101498/problem/K
题意:
给出一个数列。
定义连续子序列的权值为这里写图片描述
要求你求出两个不想交自序列的最大差值。
思路:
两次DP。

long long dmax[MAX][2];//  dp[i][j]表示以第i个数结尾的长度为奇数/偶数的连续子序列最大值long long dmin[MAX][2];//dp[i][j]表示以第i个数结尾的长度为奇数/偶数的连续子序列最小值long long cmax[MAX][2];// dp[i][j]表示以第i个数结尾的长度为奇数/偶数的第二个连续子序列最小值和第一个序列的做大差值 第一个序列大long long cmin[MAX][2];// 、、、、、、 第一个序列小
#include <algorithm>#include <cstdio>#include <cstring>#include<iostream>#include<string>#include <cstdlib>#include<queue>#include<set>using namespace std;const int MAX=2*1e5+7;long long dmax[MAX][2];//  dp[i][j]表示以第i个数结尾的长度为奇数/偶数的连续子序列最大值long long dmin[MAX][2];long long cmax[MAX][2];long long cmin[MAX][2];long long str[MAX];const long long INF=0x3f3f3f3f3f3f3f3f;int main(){    int T;    scanf("%d",&T);    while(T--)    {        int n;        scanf("%d",&n);        for(int i=1;i<=n;i++)            scanf("%lld",&str[i]);        for(int i=0;i<=n;i++)        {            dmax[i][1]=dmax[i][0]=-INF;            dmin[i][1]=dmin[i][0]=INF;            cmax[i][1]=cmax[i][0]=-INF;            cmin[i][1]=cmin[i][0]=INF;        }        for(int i=1;i<=n;i++)        {            dmax[i][1]=max(dmax[i-1][0]+str[i],str[i]);// 1为奇数 0为偶数            if(i>1) dmax[i][0]=dmax[i-1][1]-str[i];            dmin[i][1]=min(dmin[i-1][0]+str[i],str[i]);// 1为奇数 0为偶数            if(i>1) dmin[i][0]=dmin[i-1][1]-str[i];            /*printf("dmax[%d][%d]=%lld\n",i,1,dmax[i][1]);            printf("dmax[%d][%d]=%lld\n",i,0,dmax[i][0]);            printf("dmin[%d][%d]=%lld\n",i,1,dmin[i][1]);            printf("dmin[%d][%d]=%lld\n",i,0,dmin[i][0]);*/        }        long long maxs=-INF,mins=INF;        long long cntm=-INF,cnti=INF;        for(int i=2;i<=n;i++)        {            cntm=max(cntm,max(dmax[i-1][1],dmax[i-1][0]));            cmax[i][1]=max(cmax[i-1][0]-str[i],cntm-str[i]);            if(i>2) cmax[i][0]=cmax[i-1][1]+str[i];            maxs=max(maxs,max(cmax[i][1],cmax[i][0]));            cnti=min(cnti,min(dmin[i-1][1],dmin[i-1][0]));            cmin[i][1]=min(cmin[i-1][0]-str[i],cnti-str[i]);            if(i>2) cmin[i][0]=cmin[i-1][1]+str[i];            mins=min(mins,min(cmin[i][1],cmin[i][0]));            //printf("cmax[%d][%d]=%lld\n",i,1,cmax[i][1]);            //printf("cmax[%d][%d]=%lld\n",i,0,cmax[i][0]);            //printf("cmin[%d][%d]=%lld\n",i,1,cmin[i][1]);            //printf("cmin[%d][%d]=%lld\n",i,0,cmin[i][0]);        }        cout<<max(maxs,-mins)<<endl;    }}
原创粉丝点击