codefroces 33C Wonderful Randomized Sum DP

题意:在一个数字序列中,可以进行无数字的两种操作,即找出前缀,和后缀,并对这个序列乘以-1,求在可以进行这种操作的情况下,序列和的最大值

做法:怎么说呢,具体看程序吧,一开始少考虑了留出一段不进行操作的情况

#include <iostream>
#include <cstdio>
#include <cstring>
#define LMT 100003
using namespace std;
int pre[LMT],down[LMT],a[LMT],zhen[LMT],fu[LMT];
int main()
{
    int n,ans;
    bool yes=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]<0)
        {
            fu[i]=fu[i-1]+a[i];
            zhen[i]=zhen[i-1];
        }
        else
        {
            zhen[i]=zhen[i-1]+a[i];
            fu[i]=fu[i-1];
        }
        if(zhen[i]+fu[i]>-zhen[i]-fu[i])
        pre[i]=zhen[i]+fu[i];
        else pre[i]=-zhen[i]-fu[i];
        if(pre[i]<a[i]+pre[i-1])pre[i]=a[i]+pre[i-1];//不操作
    }
    memset(zhen,0,sizeof(zhen));
    memset(fu,0,sizeof(fu));
    for(int i=n;i>=1;i--)
    {
        if(a[i]>0)
        {
            zhen[i]=zhen[i+1]+a[i];
            fu[i]=fu[i+1];
        }
        else
        {
            zhen[i]=zhen[i+1];
            fu[i]=fu[i+1]+a[i];
        }
        if(zhen[i]+fu[i]>-zhen[i]-fu[i])
        down[i]=zhen[i]+fu[i];
        else down[i]=-zhen[i]-fu[i];
        if(down[i]<down[i+1]+a[i])down[i]=down[i+1]+a[i];//不操作
    }
     for(int i=0;i<=n;i++)
     if(0==yes||ans<pre[i]+down[i+1])
     {
         ans=pre[i]+down[i+1];
         yes=1;
     }
     printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(codefroces 33C Wonderful Randomized Sum DP)