洛谷P1725 琪露諾

題目描述

在幻想鄉,琪露諾是以笨蛋聞名的冰之妖精。

某一天,琪露諾又在玩速凍青蛙,就是用冰把青蛙瞬間凍起來。但是這隻青蛙比以往的要聰明許多,在琪露諾來之前就已經跑到了河的對岸。於是琪露諾決定到河岸去追青蛙。

小河可以看作一列格子依次編號爲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]

 

輸出格式:

 

一個整數,表示最大冰凍指數。保證不超過2^31-1

 

輸入輸出樣例

輸入樣例#1: 

5 2 3
0 12 3 11 7 -2

輸出樣例#1: 

11

說明

對於60%的數據:N <= 10,000

對於100%的數據:N <= 200,000

對於所有數據 -1,000 <= A[i] <= 1,000且1 <= L <= R <= N

分析

這題很容易就可以推出狀態轉移方程

f[x]=max{f[j]}+a[x];(i-r<=j<=i-l)

但如果只使用DP,時間複雜度爲O(n^2)

所以我們需要用一個單調隊列來維護

#include<iostream>
#include<stdio.h>
using namespace std;
int n,l,r,s[1000051],f[1000055];
int q[5000550],front,tail;
int main(){
	cin>>n>>l>>r;
	if(l>r) swap(l,r);
	for(int i=0;i<=n;i++)
	{
		scanf("%d",&s[i]);
	}
	front=tail=1;
	for(int i=l;i<=n+r;i++)
	{
		while(front<tail&&f[q[tail-1]]<f[i-l])
		tail--;
		q[tail++]=i-l;
		while(front<tail&&q[front]<i-r)
		front++;
		f[i]=f[q[front]]+s[i];
	}
	int maxn=0;
	for(int i=n;i<=n+r;i++)
	{
		maxn=max(maxn,f[i]);
	}
	cout<<maxn;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章