期望得分: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; }