Codeforces Educativos Ronda 103 (Clasificado para la Div. 2) D. Viaje (dp)

Descripción del Título

Hay n + 1 ciudades, numeradas de 0 a n. n carreteras conectan estas ciudades, la i-ésima carretera conecta las ciudades i − 1 e i (i∈ [1, n]).
Cada camino tiene una dirección. Las direcciones vienen dadas por una cadena de n caracteres de modo que cada carácter sea L o R. Si el i-ésimo carácter es L, significa que la i-ésima carretera va inicialmente de la ciudad i a la ciudad i − 1; de lo contrario, va de la ciudad i − 1 a la ciudad i.
Un viajero quisiera visitar tantas ciudades de este país como sea posible. Inicialmente, elegirán alguna ciudad para comenzar su viaje. Cada día, el viajero debe ir de la ciudad donde se encuentra actualmente a una ciudad vecina por una de las carreteras, y puede ir por una carretera solo si está dirigida en la misma dirección que va; I. e., si una carretera se dirige de la ciudad i a la ciudad i + 1, es posible viajar de i a i + 1, pero no de i + 1 a i. Después de que el viajero se traslada a una ciudad vecina, todas las carreteras cambian de dirección a las opuestas. Si el viajero no puede ir de su ciudad actual a una ciudad vecina, su viaje termina; También es posible finalizar el viaje cuando el viajero lo desee.
El objetivo del viajero es visitar tantas ciudades diferentes como sea posible (puede visitar una ciudad varias veces, pero solo se cuenta la primera visita). Para cada ciudad i, calcule el número máximo de ciudades diferentes que el viajero puede visitar durante exactamente un viaje si comienza en la ciudad i.

Aporte

La primera línea contiene un número entero t (1≤t≤104) - el número de casos de prueba.
Cada caso de prueba consta de dos líneas. La primera línea contiene un número entero n (1≤n≤3⋅105). La segunda línea contiene la cadena s que consta de exactamente n caracteres, cada carácter es L o R.
Se garantiza que la suma de n en todos los casos de prueba no exceda 3⋅105.

Producción

Para cada caso de prueba, imprima n + 1 enteros. El i-ésimo entero debe ser igual al número máximo de ciudades diferentes que el viajero puede visitar durante un viaje si este viaje comienza en la i-ésima ciudad.

Ejemplo

entrada
2
6
LRRRLL
3
LRL
salida
1 3 2 3 1 3 2
1 4 1 4

Idea general

Dados n bordes, hay n + 1 ciudades diferentes, y cada borde tiene una dirección:
L significa que hay un borde de i a i-1, y
R significa que hay un borde de i a i + 1.
Los turistas van de cada A partir de la ciudad i, cada vez que llegue a la siguiente ciudad, todos los bordes se invertirán, L se convertirá en R y R se convertirá en L. Para cada ciudad, cuál es el número máximo de ciudades a las que puede llegar un viajero.

Análisis de temas

Para cada respuesta, podemos dividirla en tres partes:
1) La ciudad de partida en sí: 1.

2) El número de ciudades a las que se puede llegar yendo a la izquierda pre [i], porque cada paso invertirá todos los bordes, por lo tanto pre[i]=从i开始向左LRLR序列的最大长度.
Podemos pensar en cómo se obtiene pre [i]: De hecho, es un simple dp.
Si s [i] = 'L' ys [i-1] = 'R', entonces pre[i]=pre[i-2]+2;
si s [i] = ' L ', entonces de lo pre[i]=1;
contrario,pre[i]=0;

3) El número de ciudades a las que se puede llegar yendo hacia la derecha es suf [i], lo mismo ocurre suf[i]=从i+1开始向右RLRL序列的最大长度.
El proceso de resolver suf [i] es el mismo que la idea de resolver pre [i], así que no diré más aquí.

el código se muestra a continuación
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <bitset>
#include <algorithm>
#define LL long long
#define PII pair<int,int>
#define x first
#define y second
using namespace std;
const int N=3e5+5;
char s[N];
int pre[N],suf[N];
int main()
{
    
    
    int t;
	scanf("%d",&t);
	while(t--)
	{
    
    
		int n;
		scanf("%d",&n);
		scanf("%s",s+1);
		for(int i=0;i<=n+1;i++) pre[i]=suf[i]=0;		//清空pre[]和suf[]
		for(int i=1;i<=n;i++)				//求出pre[]
		{
    
    
			if(s[i]=='L'&&s[i-1]=='R') pre[i]=pre[i-2]+2;
			else if(s[i]=='L') pre[i]=1;
		}
		for(int i=n-1;i>=0;i--)				//求出suf[]
		{
    
    
			if(s[i+1]=='R'&&s[i+2]=='L') suf[i]=suf[i+2]+2;
			else if(s[i+1]=='R') suf[i]=1;
		}
		for(int i=0;i<=n;i++)				//第i个城市能到多少点即为三部分内容的相加
			printf("%d ",pre[i]+suf[i]+1);
		puts("");
	}
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/li_wen_zhuo/article/details/113432840
Recomendado
Clasificación