最大連續子序列和(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;i<n;i++)
{
    if(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 <bits/stdc++.h>
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;i<n;i++)
    {
        if(mm[i]==duo)
           ll[i]=1;
        else if(mm[i]==shao)
           ll[i]=-1;
        else ll[i]=0;
    }
    for(int j=0;j<n;j++)
    {
        if(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;h<n;h++)
    {
                if(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<n;i++)
        {
            scanf("%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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章