Experimento de la batería
Garutoujun está jugando un juego de simulación de guerra. Tiene un fuerte con alturas de 1, 2, 3, ..., n . Necesita alinear los n fuertes de izquierda a derecha, y los bozales están todos hacia la derecha .
En este juego, los proyectiles disparados por todas las torretas destruirán todas las torretas en el frente que sean más bajas que ellas. Cada vez que el rey del ajo n la fortaleza en una fila, puede haber alguna fortaleza fue destruida. Por ejemplo: actualmente hay 5 torretas, y de izquierda a derecha, la altura es 2,1,3,5,4. Después de disparar proyectiles a la derecha, la torreta con una altura de 4 es destruida por una altura de 5, y la torreta con una altura de 1 es Las torretas con una altura de 2 se destruyen, y solo quedarán tres torretas de 2, 3 y 5.
Ahora la cabeza de ajo quiere saber, si los n fuertes se colocan al azar , ¿cuál es el número esperado de fuertes restantes? Por ejemplo , cuando n = , hay dos métodos de colocación, la secuencia de altura es 1 , 2 y 2 , 1 respectivamente , el primero tiene 22 torretas restantes y el último tiene una torre izquierda, por lo que la expectativa es (2 + 1) \ 2 = 1.5000 .
Encuentre la expectativa del número de fuertes restantes cuando n = 201 , y mantenga cuatro decimales.
Copia de entrada de muestra
Ninguno
Copia de salida de muestra
Ninguno
Fuente de la pregunta
Torneo de demostración del Grupo A del Campeonato Provincial Blue Bridge Cup 2019 (1)
Idea uno (tiempo de ejecución prolongado, falla):
Después de crear una matriz arr [2019] , asigne valores a 1, 2, 3 ... 2019 respectivamente . Luego use la función next_permutation () para ingresar todas las permutaciones, y luego use un bucle para eliminar los números que son menores que los anteriores.
El código es el siguiente:
#include <iostream> #include <algorithm> #include < string > #include <cstring> #include <cstdio> usando el espacio de nombres std; #define N 9 int main () { int arr [ 2019 ]; para ( int i = 0 ; i <N; ++ i) { arr [i] = i + 1 ; } doble num1 = 0 , num2 = 0 ; hacer { boolb [ 2019 ] = { 0 }; num2 ++ ; para ( int i = 0 ; i <N; ++ i) { para ( int j = i + 1 ; j <N; ++ j) { if (arr [i]> arr [j]) b [j] = 1 ; } } para ( int i = 0 ; i <N; ++ i) { if (! b [i]) num1 ++ ; } } mientras(next_permutation (arr, arr + N)); printf ( " % .4f " , num1 / num2); devuelve 0 ; }
Después de ejecutar el descubrimiento, la idea es muy buena, pero debido a la gran cantidad de bucles, el compilador necesita mucho tiempo y puede calcular la situación de n = 20, que todavía está lejos de 2019, por lo que esta idea tiene que cambiarse, por lo que surgió La segunda idea
Idea dos:
Debido a que la pregunta busca el valor esperado, como el número 2019, no importa cómo organice el número 2019, el valor esperado del número 2019 es 1; el número 2018 solo se puede eliminar cuando 2019 está frente a él, por lo que el valor esperado del número 2018 Es 1/2; de manera similar, cuando n = 2019, se puede resolver con solo un ciclo 1 / i.
El código es el siguiente:
#include <cstdio> #include <iostream> usando el espacio de nombres std; int main () { double num = 0 ; int n = 2019 ; para ( int i = 1 ; i <= n; i ++ ) { num + = 1.0 / i; } printf ( " % .4f \ n " , num); devuelve 0 ; }