Para una clase de problemas de construcción. Siempre descubro la situación que no se puede construir, y luego pienso en la construcción.
En este problema, si este k puede construirse entre los tiempos de construcción mínimo y máximo, entonces puede construirse
La pregunta ahora es cómo encontrar el mínimo y el máximo. Para la inversión del título, también podríamos considerarlo como un intercambio, por lo que el caso más pequeño es en realidad un intercambio una vez, es decir, el número de pares en orden inverso
La situación más grande es cambiar todos los artículos intercambiables cada vez. En primer lugar, podemos pensar que cada pariente debe ser relativo cuando no hay intercambio, es decir, debe intercambiarse, independientemente del número de otros equipos, por lo que todo intercambio es lo mejor para cada intercambio.
Ahora considere cómo cambiar lentamente el número de veces del valor mínimo al valor máximo.
Debo haber pensado, por ejemplo, que podemos intercambiar las tres posiciones 1 3 5 antes
Primero intercambiamos 1 3 y luego intercambiamos 5 para expandir con éxito una vez
Siempre que se pueda construir de acuerdo con esto.
Consideramos comenzar con el último conjunto de intercambios. De hecho, también podemos comenzar con el primer intercambio, pero esto es más complicado de escribir.
Luego, solo saque el último fragmento del grupo más pequeño original y cámbielo a uno nuevo. Si resulta que un grupo se ha ido, vaya al grupo anterior.
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <map> #include < string > #include <vector> usando el espacio de nombres std; typedef vector < int > VI; const int N = 3000010 ; int n, k; cuerda s; int tot, idx, cnt; vector < int > ans [N]; int main () { cin >> n >> k; cin>> s; int i, j; while ( 1 ) { for (i = 0 ; i <( int ) s.size () - 1 ; i ++ ) { if (s [i] == ' R ' && s [i + 1 ] == ' L ' ) { ans [idx] .push_back (i); cnt ++ ; } } if (ans [idx] .empty ()) break ; if (idx> = k) { cout<<" -1 " << endl; devuelve 0 ; } idx ++ ; for (auto x: ans [idx- 1 ]) { swap (s [x], s [x + 1 ]); } } if (k> cnt) { cout << - 1 << endl; devuelve 0 ; } int m = idx- 1 ; para (i = k- 1 ; i> = 0 ; i-- ) { if(ans [m] .empty ()) m - ; if (! ans [i] .empty ()) se rompe ; ans [i] .push_back (ans [m] .back ()); ans [m] .pop_back (); } para (i = 0 ; i <k; i ++ ) { printf ( " % d \ n " , ( int ) ans [i] .size ()); para (auto x: ans [i]) { printf ( " % d " , x + 1 ); } printf ( " \ n " ); } volver 0 ; }