histcat

histcat

P1725 Cirno

Problem#

Cirno#

Problem Description#

The small river can be viewed as a series of cells numbered from $0$ to $N$, and Cirno can only move from a cell with a smaller number to a cell with a larger number. Moreover, Cirno moves in a special way; when she is at cell $i$, she can only move to any cell in the range $[i+L,i+R]$. You may wonder why she moves this way, and it's simple: because she is a fool.

Each cell has a freezing index $A_i$, with the cell numbered $0$ having a freezing index of $0$. When Cirno stays in a cell, she can obtain the freezing index $A_i$ of that cell. Cirno hopes to obtain the maximum freezing index by the time she reaches the other side, so she can teach that frog a lesson.

However, since she is quite foolish, she has decided to ask you to help her decide how to proceed.

At the start, Cirno is on cell numbered $0$, and as long as her next position number is greater than $N$, she has reached the other side.
$N \le 2\times 10^5$

Solution#

Let f[i] represent the maximum value that can be obtained when reaching i.

The transition is also easy to think of, which will be T.

Think about it; a monotonic queue can be used to optimize the dp.

The monotonic queue maintains the maximum value of f in the range from i-R to i-L.

(Points to note when writing the monotonic queue:

  1. Use while for head and tail processing.
  2. Understand that the monotonic queue stores indices.)

!!!! Don't forget to initialize! Just like this set of data, some points are unreachable.
6 2 2 0 1 -1 1 -1 1 -1
Should be -3

Code#

#include<bits/stdc++.h>
const int N = 2e5 + 10;
using namespace std;
int read()
{
	int f = 1, x = 0;
	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 f * x;
}


int n, L, R;
int a[N], f[N];

int qwq[N], h = 1, t = 0;


int main()
{
	n = read(), L = read(), R = read();
	
	n ++;//!!!! 
	for(int i = 1;i <= n;i++) f[i] = -0x3f3f3f3f;
	f[1] = 0;
	for(int i = 1;i <= n;i++)
	{
		a[i] = read();
	}
	int ans = -0x3f3f3f3f;
	for(int i = 1;i <= n;i++)
	{
		if(i - L >= 1)
		{
			while(t >= h && f[i - L] >= f[qwq[t]]) t--;
			qwq[++t] = i - L;
			while(qwq[h] < i - R) h++;
			f[i] = f[qwq[h]] + a[i];
		}

		if(i + R > n) ans = max(ans, f[i]);
	}
	printf("%d", ans);
	
	return 0;
}
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.