CF573B Bear and Blocks 题 解

Es un poco difícil pensar en esta pregunta y debe pensarse en función del significado y los ejemplos de la pregunta.

Primero consideramos ai a_iayo Bajará a 0 después de algunas veces.

El siguiente análisis solo considera la situación en la que se destruye la parte superior de la columna y no considera que el impacto de la altura de las columnas izquierda y derecha sea 0.

  1. 如果ai ≤ ai - 1 a_i \ leq a_ {i - 1}ayoai - 1ai ≤ ai + 1 a_i \ leq a_ {i + 1}ayoai + 1, Entonces solo la rejilla superior sufrirá, los tiempos de consumo ai a_iayo
  2. No, ai = min ⁡ (ai - 1, ai + 1) a_i = \ min {(a_ {i --1}, a_ {i + 1})}ayo=min( uni - 1,ai + 1) , En este momento podemos calcular mediante fuerza bruta.

Pero hay una manera mejor?

Sabemos que para este tipo de problema mínimo, normalmente se puede utilizar dp para resolverlo.

Configuración fi f_iFyo为 第iiLa cantidad de veces que se destruyen i pilares, luego, de acuerdo con el análisis anterior, tenemos una ecuación de transición de estado: fi = max ⁡ (fi - 1 + 1, ai, fi + 1 + 1) f_i = \ max {(f_ { i-1} + 1, a_i, f_ {i + 1} + 1)}Fyo=max( fi - 1+1 ,ayo,Fi + 1+1 )

Considerando que para fi f_iFyo Necesitamos usar los datos de la izquierda y la derecha al mismo tiempo, luego podemos hacer dos dp para resolver.

Ahora consideremos la situación a la izquierda y a la derecha.

De hecho, solo necesitamos agregar un pilar virtual con una altura de 0 en los lados izquierdo y derecho, qwq.

Código:

#include <bits/stdc++.h>
#define Max(a, b) ((a > b) ? a : b)
#define Min(a, b) ((a < b) ? a : b)
using namespace std;

typedef long long LL;
const int MAXN = 1e5 + 10;
int n, a[MAXN], f[MAXN], ans;

int read()
{
    
    
	int sum = 0, fh = 1; char ch = getchar();
	while (ch < '0' || ch > '9') {
    
    if (ch == '-') fh = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9') {
    
    sum = (sum << 3) + (sum << 1) + (ch ^ 48); ch = getchar();}
	return sum * fh;
}

int main()
{
    
    
	n = read();
	for (int i = 1; i <= n; ++i) a[i] = read();
	for (int i = 1; i <= n; ++i) f[i] = Min(f[i - 1] + 1, a[i]);
	for (int i = n; i >= 1; --i) f[i] = Min(f[i + 1] + 1, f[i]);
	for (int i = 1; i <= n; ++i) ans = Max(ans, f[i]);
	printf("%d\n", ans);
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/BWzhuzehao/article/details/112493387
Recomendado
Clasificación