「NOIP模拟赛」琪露诺
题目描述 | 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精。某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来。但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸。于是琪露诺决定到河岸去追青蛙。小河可以看作一列格子依次编号为0到N,琪露诺只能从编号小的格子移动到编号大的格子。而且琪露诺按照一种特殊的方式进行移动,当她在格子i时,她只会移动到i+L到i+R中的一格。你问为什么她这么移动,这还不简单,因为她是笨蛋啊。每一个格子都有一个冰冻指数A[i],编号为0的格子冰冻指数为0。当琪露诺停留在那一格时就可以得到那一格的冰冻指数A[i]。琪露诺希望能够在到达对岸时,获取最大的冰冻指数,这样她才能狠狠地教训那只青蛙。但是由于她实在是太笨了,所以她决定拜托你帮它决定怎样前进。开始时,琪露诺在编号0的格子上,只要她下一步的位置编号大于N就算到达对岸。 |
输入格式 | 第1行:3个正整数N, L, R
第2行:N+1个整数,第i个数表示编号为i-1的格子的冰冻指数A[i-1] |
输出格式 | 第1行:一个整数,表示最大冰冻指数。保证不超过2^31-1
第2行:空格分开的若干个整数,表示琪露诺前进的路线,最后输出-1表示到达对岸 |
输入样例 | 5 2 3
0 12 3 11 7 -2 |
输出样例 | 11
0 3 -1 |
数据范围 | 对于60%的数据:N <= 10,000
对于100%的数据:N <= 200,000 对于所有数据 -1,000 <= A[i] <= 1,000且1 <= L <= R <= N |
注意 | 此题采用Special Judge |
f[i] = Max{f[j]} + A[i]; (i – R <= j <= i – L)
最后取从f[N – R + 1]到f[N]中的最大值。
然后用个堆维护最大值。。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<queue> #define pa pair<int,int> #define inf 1000000000 #define ll long long using namespace std; int n,l,r,head,tail=1,top; int a[200005],f[200005],from[200005]; int pos[200005],v[200005],arr[200005]; int ans,mx=-inf; priority_queue<pa,vector<pa> > q; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int main() { //freopen("iceroad.in","r",stdin); //freopen("iceroad.out","w",stdout); n=read();l=read();r=read(); for(int i=0;i<=n;i++)a[i]=read(); for(int i=1;i<=n;i++) { if(i<l)f[i]=-inf; else { int now=q.top().second; while(now<i-r) { q.pop();now=q.top().second; } from[i]=now;f[i]=f[now]+a[i]; } if(i-l+1>=0&&f[i-l+1]!=-inf)q.push(make_pair(f[i-l+1],i-l+1)); } for(int i=n-r+1;i<=n;i++) { if(f[i]>mx){mx=f[i];ans=i;} } printf("%d\n",mx); for(int i=ans;i;i=from[i]) arr[++top]=i; printf("0 "); for(int i=top;i;i--) printf("%d ",arr[i]); printf("-1"); return 0; } |
难道不是用单调队列吗?
无所谓