最大连续子序列和(xdoj 1079)

惯例先贴题目:西电oj 1079 http://acm.xidian.edu.cn/problem.php?id=1079

最大连续子序列和的标准算法:时间复杂度o(n)
设所给序列为a[n]
定义sum[i]为以i结尾的最大连续子区间和,
易找到递推关系sum[i]=max(0,sum[n-1])+a[i]
所以只需要用for循环扫描一遍。

forint i=1;i<=n;i++)
{
    last=max(0,last)+a[i];
    ans=max(ans,last);
}

若上面的代码不好理解,你也可以写成这样,一样的思路和复杂度

int sum=0,max=0;
for(int i=0;iif(sum<0)
        sum=a[i];
    else 
        sum+=a[i];
    if(sum>max)
    max=sum;
}

下面是1079的题解

这个题首先需要两层for循环枚举子序列中最多的数和最少的数。
设最多的数为i,最少的数为j
然后处理原数组
原数组中==i的数处理成1,==j的数处理成-1,其他数处理成0;
然后求最大子序列和就是最大差值 //每出现一次最多的数,差值+1,每出现一次最少的数,差值-1
不过这里需要注意如果是这样的数据:1 0 1 1 1 1 1
上述方法得到的值是6,明显是错误的
所以需要判断。
如果得到的子序列中存在-1,那么求得的差就是所求的差
如果得到的子序列中不存在-1,且整个数列中不存在-1,那么这时的差=0,因为只出现了一个数,没有可比性
如果得到的子序列中不存在-1,且整个数列中存在-1,那么这时的差-1就是所求。

下面是代码

#include 
using namespace  std;

int mm[100005],ll[100005];

int solve(int duo,int shao,int n)
{
    int ma=0,ans=0,flag=0,flagg=0,e=0,f=0,ee=0,ff=0;
    for(int i=0;iif(mm[i]==duo)
           ll[i]=1;
        else if(mm[i]==shao)
           ll[i]=-1;
        else ll[i]=0;
    }
    for(int j=0;jif(ll[j]==-1)
           flag++;
        if(ans<0)
        {
            ans=ll[j];
            e=j;
            f=j;
            flag=0;
            if(ll[j]==-1)
              flag=1;
        }
        else
        {
            ans+=ll[j];
            e++;
        }
        if(ans>ma || (ans==ma&&flagg<1))
        {
            ma=ans;
           ff=f;
           ee=e;
           flagg=flag;
        }
    }
    if(flagg)
        return  ma;
    for(int k=ff;k>=0;k--)
    {
                if(ll[k]==-1)
                    return ma-1;
    }
   for(int h=ee;hif(ll[h]==-1)
                    return ma-1;
    }
    return 0;
}

int main() 
{
    int T,ma=0;
    scanf("%d",&T);
    while(T--)
    {
        ma=0;
        int m,n;
        scanf("%d %d",&n,&m);
        for(int i=0;i"%d",&mm[i]);
        }
        for(int j=1;j<=m;j++)
        for(int k=1;k<=m;k++)
        {
            if(j!=k)
            {
                ma=max(ma,solve(j,k,n));
            }
        }
        printf("%d\n",ma);
    }

    return 0;
}

你可能感兴趣的:(xdoj,acm水题)