Dirección: https://cometoj.com/contest/76/problem/A?problem_id=4237
Análisis: Este problema es relativamente simple de resolver con DP. No he entendido otras soluciones. La llamada ola, un solo número no se puede contar, dos números deben contar. En nuestra dp bidimensional, j = 0 significa descendente o igual, y j = 1 significa ascendente. i de 0 a n
Ecuación de transferencia:
if (a [i- 1 ] <= a [i]) { dp [i] [ 0 ] = dp [i- 1 ] [ 1 ] + 1 ; } más dp [i] [ 1 ] = dp [i- 1 ] [ 0 ] + 1 ; suma + = dp [i] [ 0 ] + dp [i] [ 1 ];
Tome una muestra para explicar:
Podemos escribir algo como esto: 0 1
1 0 1
2 0 1
3 2 0
4 1 0
Suma por suma es la respuesta. En el primer paso, comenzando desde i = 1 y aumentando, dp [1] [1] = dp [0] [0] +1;
En el segundo paso, i = 2, 2-> 3 sigue subiendo, pero dp [2] [1] no puede aceptar el dp anterior [1] [1], porque los tres números crecientes no son ondas, y necesitan realizar dp [0] [ 1], más 1 (casi un reinicio)
El tercer paso, i = 3,3-> 2, hay una disminución, dp [3] [0] = dp [2] [1] + 1 = 2, aquí para explicar, se guarda dp [2] [1] 2-> 3, el 1 en +1 es el nuevo 3-> 2, el 2-> 3 original está conectado a 3-> 2, el número sigue siendo ese número, es decir, dp [3] [0] = dp [2 ] [1] + 1 = 2.
En general, en esta ecuación de transferencia, +1 es la nueva onda actual agregada, y la dp en el paso anterior es la onda anterior conectada a esta nueva onda. El número sigue siendo la dp anterior, pero la apariencia es diferente. Sí, así que usa la suma para acumular.
#include <iostream> #include <cstdio> #include <cstring> usando el espacio de nombres std; typedef largo largo ll; const int maxn = 3e6 + 10 ; int dp [maxn] [ 2 ]; int a [maxn]; int main () { int n; cin >> n; para ( int i = 0 ; i <n; i ++ ) cin >> a [i]; ll suma = 0 ; para( int i = 1 ; i <n; i ++ ) { if (a [i- 1 ] <= a [i]) { dp [i] [ 0 ] = dp [i- 1 ] [ 1 ] + 1 ; } más dp [i] [ 1 ] = dp [i- 1 ] [ 0 ] + 1 ; suma + = dp [i] [ 0 ] + dp [i] [ 1 ]; } cout << sum << endl; }