送分题(songfen)

Time Limit:1000ms   Memory Limit:128MB

题目描述

LYK喜欢干一些有挑战的事,比如说求区间最大子段和。它知道这个题目有O(n)的做法。于是它想加强一下。

也就是说,LYK一开始有n个数,第i个数字是ai,它找来了一个新的数字P,并想将这n个数字中恰好一个数字替换成P。要求替换后的最大子段和尽可能大。

LYK知道这个题目仍然很简单,于是就扔给大家来送分啦~

注:最大子段和是指在n个数中选择一段区间[L,R](L<=R)使得这段区间对应的数字之和最大。

 

输入格式(songfen.in)

    第一行两个数n,P。

    接下来一行n个数ai。

 

输出格式(songfen.out)

    一个数表示答案。

 

输入样例

5 3

-1 1 -10 1 -1

 

输出样例

5

 

样例解释

将第三个数变成3后最大子段和为[2,4]。

 

数据范围

对于30%的数据n<=100。

对于另外30%的数据ai,P>=0。

对于100%的数据n<=1000,-1000<=ai,P<=1000。

 

Note:提前AK的同学可以想一想O(n)的做法。

 

枚举改哪个,再做O(n)的最大子段和。总复杂度:O(n²)

O(n)做法用栈,不会。。。。。。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,p,ans,tmp,out=-1e8;
int dp[1001],a[1001];
int main()
{
    freopen("songfen.in","r",stdin);
    freopen("songfen.out","w",stdout);
    scanf("%d%d",&n,&p);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    int x;
    for(int k=1;k<=n;k++)
    {
        tmp=a[k];     a[k]=p; 
        for(int i=1;i<=n;i++)
        {
            x=a[i];
            if(dp[i-1]+x>=x) dp[i]=dp[i-1]+x;
            else dp[i]=x;
            if(dp[i]>ans) ans=dp[i];
        }
        out=max(out,ans);
        a[k]=tmp;
        memset(dp,0,sizeof(dp));
        ans=-1e8;
    }
    printf("%d",out);
}
View Code

相关文章: