Expérience de batterie
Ail juin jouer à un jeu de guerre simulée, il a une hauteur de 1,2,3, ..., n sont chacun un fort, il a besoin de mettre n fort de gauche à droite dans une rangée, et le museau sont vers la droite .
Dans ce jeu, les obus tirés par toutes les tourelles détruiront toutes les tourelles en avant qui sont plus basses qu'eux. Lorsque la tête d'ail Jun a aligné n forts, certains forts pourraient être détruits. Par exemple: il y a actuellement 5 tourelles, et de gauche à droite, la hauteur est de 2,1,3,5,4. Après avoir tiré des obus vers la droite, la tourelle d'une hauteur de 4 est détruite par une hauteur de 5 et la tourelle d'une hauteur de 1 est Les tourelles d'une hauteur de 2 sont détruites et seules trois tourelles de 2, 3 et 5 resteront.
Maintenant, la tête d'ail veut savoir, si les n forts sont placés au hasard , quel est le nombre attendu de forts restants? Par exemple , lorsque n = , il existe deux méthodes de placement, la séquence de hauteur est respectivement 1 , 2 et 2 , 1 , la première a 22 tourelles restantes et la seconde a une tourelle gauche, donc l'attente est (2 + 1) \ 2 = 1,5000 .
Veuillez trouver l'espérance du nombre de forts restants lorsque n = 201 , et garder quatre décimales.
Exemple de copie d'entrée
Aucun
Exemple de copie de sortie
Aucun
Source de la question
Tournoi de démonstration du groupe A du championnat provincial de la Coupe Blue Bridge 2019 (1)
Première idée (longue durée de fonctionnement, échec):
Après avoir créé un tableau arr [2019] , affectez des valeurs à 1, 2, 3 ... 2019 respectivement . Utilisez ensuite la fonction next_permutation () pour saisir toutes les permutations, puis utilisez une boucle pour supprimer les nombres inférieurs aux précédents.
Le code est le suivant:
#include <iostream> #include <algorithm> #include < string > #include <cstring> #include <cstdio> using namespace std; #define N 9 int main () { int arr [ 2019 ]; pour ( int i = 0 ; i <N; ++ i) { arr [i] = i + 1 ; } double num1 = 0 , num2 = 0 ; faire { boolb [ 2019 ] = { 0 }; num2 ++ ; for ( int i = 0 ; i <N; ++ i) { for ( int j = i + 1 ; j <N; ++ j) { if (arr [i]> arr [j]) b [j] = 1 ; } } pour ( int i = 0 ; i <N; ++ i) { if (! b [i]) num1 ++ ; } } tout(next_permutation (arr, arr + N)); printf ( " % .4f " , num1 / num2); retourner 0 ; }
Après avoir exécuté la découverte, l'idée est très bonne, mais en raison du grand nombre de boucles, le compilateur a besoin de beaucoup de temps, et il peut calculer la situation de n = 20, ce qui est encore loin de 2019, donc cette idée doit être modifiée, donc elle est venue La deuxième idée.
Deuxième idée:
Parce que la question recherche la valeur attendue, comme le nombre 2019, peu importe la façon dont vous organisez le nombre 2019, la valeur attendue du nombre 2019 est 1; le nombre 2018 ne peut être éliminé que lorsque 2019 est devant lui, donc la valeur attendue du nombre 2018 Il est 1/2; de même, lorsque n = 2019, il peut être résolu avec un seul cycle 1 / i.
Le code est le suivant:
#include <cstdio> #include <iostream> utilisant l' espace de noms std; int main () { double num = 0 ; int n = 2019 ; pour ( int i = 1 ; i <= n; i ++ ) { num + = 1.0 / i; } printf ( " % .4f \ n " , num); retourner 0 ; }