期望得分:100+100+50=250

实际得分:100+70+50=220

 

T1 最大值(max)

Time Limit:1000ms   Memory Limit:128MB

 

题目描述

LYK有一本书,上面有很多有趣的OI问题。今天LYK看到了这么一道题目:

这里有一个长度为n的正整数数列ai(下标为1~n)。并且有一个参数k。

你需要找两个正整数x,y,使得x+k<=y,并且y+k-1<=n。并且要求a[x]+a[x+1]+…+a[x+k-1]+a[y]+a[y+1]+…+a[y+k-1]最大。

LYK并不会做,于是它把题扔给了你。

 

输入格式(max.in)

第一行两个数n,k。

    第二行n个数,表示ai。

 

输出格式(max.out)

两个数表示x,y。若有很多种满足要求的答案,输出x最小的值,若x最小仍然还有很多种满足要求的答案,输出y最小的值。 

 

输入样例

5 2

6 1 1 6 2

 

输出样例

1 4

 

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

对于60%的数据n<=1000

对于100%的数据1<=n<=100000,1<=k<=n/2,1<=ai<=10^9。

 

维护连续的k个数的和 的后缀最大值

#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 100001
using namespace std;
typedef long long LL;
LL sum[N],p[N],suf[N];
int pos[N];
void read(LL &x)
{
    x=0; char c=getchar();
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
}
int main()
{
    freopen("max.in","r",stdin);
    freopen("max.out","w",stdout);
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) read(sum[i]),sum[i]+=sum[i-1];
    for(int i=1;i+k-1<=n;i++) p[i]=sum[i+k-1]-sum[i-1];
    for(int i=n-k+1;i;i--) 
        if(p[i]>=suf[i+1]) suf[i]=p[i],pos[i]=i;
        else suf[i]=suf[i+1],pos[i]=pos[i+1];
    int ansx,ansy;
    LL maxn=0;
    for(int i=1;i+k+k-1<=n;i++)
        if(p[i]+suf[i+k]>maxn) maxn=p[i]+suf[i+k],ansx=i,ansy=pos[i+k];
        else if(p[i]+suf[i+k]==maxn && ansy>pos[i+k]) ansy=pos[i+k];
    printf("%d %d",ansx,ansy);
    return 0; 
}
View Code

相关文章:

  • 2021-11-13
  • 2021-07-30
  • 2021-10-25
  • 2021-12-02
  • 2022-02-13
  • 2021-11-04
  • 2021-08-18
  • 2022-01-24
猜你喜欢
  • 2021-10-12
  • 2022-02-04
  • 2021-07-14
  • 2021-12-11
  • 2021-07-30
  • 2022-02-11
  • 2021-10-29
相关资源
相似解决方案