Technology sharing

Algorithmus Studiorum Praecipuorum (8) - Basics Programmationis Dynamicae

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Tabula contentorum

Praecipua contenta:

Programmatio dynamica:

Problemata ad programmationem dynamicam intelligendam introducuntur:

Analysis: (regressio vehemens)

Exemplum codicis:

Investigatio inhumana:

Exemplum codicis Dfs: (quaero)

Recursus arboris ex vi recursionis generatae;

Memoized quaero:

Exemplum codicis:

Programmatio dynamica:

Exemplum codicis: (programma dynamica, incipiens a minimo subprobrio)

Processus exsecutionis (programma dynamicus):

Analysis: (dynamica programmatio)

Spatium ipsum:

Exemplum codicis:

Analysis:


Praecipua contenta:

Quid programmatio dynamica, quae problemata dynamica programmatio solvere potest ut medium, classificationem programmandi dynamicam et classificationem quaestionum specificarum quae specificae classificationes solvere possunt.

Programmatio dynamica:

Algorithmus magni momenti est paradigma, quod problema in seriem minorum problematum corrumpit et repetitas calculos vitat solutiones problematum accommodans sub-solutionis, ita multo tempore efficientiam meliorem.

Problemata ad programmationem dynamicam intelligendam introducuntur:

Quaestio haec per casum ascensionis gradus introducitur. Gradibus n gradibus dato in toto, potes singulis gradibus ascendere 1 vel 2 gradus.

Analysis: (regressio vehemens)

Huius quaestionis finis est invenire numerum solutionum;Considerare possumus omnia possibilia per REGRESSUS adaequate absumens . Speciatim finge scalas ascendentes sicut processus multi- rotundi lectionis: incipiens a terra, eligens unum vel duos gradus singulos rotundos, addito 1 numero optionum quotiescumque cacumen scalarum attingis, et numerum optionum augendo, cum cacumen scalae attingis.

codice exemplum

  1. # python代码示例
  2. def backrack(choices,state,n,res) :
  3. if state == n :
  4. res[0] += 1
  5. for choice in choices :
  6. if state + choice > n :
  7. continue
  8. backrack(choices,state+choice,n,res)
  9. def climbing_stairs_backrack(n) :
  10. choices = [1,2]
  11. state = 0
  12. res = [0]
  13. backrack(choices,state,n,res)
  14. return res[0]
  15. n = int(input())
  16. print(climbing_stairs_backrack(n))
  1. // c++代码示例
  2. void backrack(vector<int> &choices, int state, int n, vector<int> &res)
  3. {
  4. if (state == n )
  5. {
  6. res[0]++ ;
  7. }
  8. for (auto &choice : choices)
  9. {
  10. if (state + choice > n)
  11. {
  12. continue ;
  13. }
  14. backrack(choices, state + choice, n, res)
  15. }
  16. }
  17. int climbingStairsBackrack(int n)
  18. {
  19. vector<int> choices = {1 , 2 } ;
  20. int state = 0 ;
  21. vector<int> res = [0] ;
  22. backrack(choices, state, n, res) ;
  23. return res[0] ;
  24. }

Investigatio inhumana:

Algorithmi regressi plerumque quaestionem explicite non dejiciunt, sed quaestionem tractant ut seriem decernendi gradus, et per heuristicos et putationes solutiones omnes possibilia quaerunt.

Hanc quaestionem resolvere conemur ex contextu compositionis problematum. Pone solutiones dp[i]scendi ad gradum i-th, tum dp[i] problema originale, eiusque problemata sub- includunt:

dp[i-1],dp[i-2],dp[1]

Cum tantum 1 vel 2 gradus in singulis rotundis ascendere possumus, cum scalae i-th stamus, tantum in i-1 vel i-2 gradibus in gyro priore stare potuimus. Aliis verbis, solum a gradu i-1 vel i-2 ad gradum i-th movere possumus.

Ex hoc magnum coniecturam facere possumus: numerus consiliorum, qui ad gradum i-1th ascenderunt, plus numerus consiliorum, quae ad gradum i-2th ascenderunt, aequalis est numerus consiliorum quae ad i ascenderunt. -th gradu. Formula haec est:

dp[i] = dp[i-1] + dp[i-2]

Hoc significat relationem recursive in aedificatione ascensu problematum, et quaestio originalis solvi potest solutionibus problematum sub- construendis.

Exemplum codicis Dfs: (quaero)

  1. # python 代码示例
  2. def dfs(i : int) -> int :
  3. if i == 1 or i == 2 :
  4. return i
  5. count = dfs(i - 1) + dfs(i - 2)
  6. return count
  7. def climbing_stairs_dfs(n : int) -> int :
  8. retunr dfs(n)
  1. // c++ 代码示例
  2. int dfs(int i)
  3. {
  4. if (i == 1 || i == 2)
  5. {
  6. return i ;
  7. }
  8. int count = dfs(i - 1) + dfs(i - 2);
  9. return count ;
  10. }
  11. int climbingStairsDFS(int n)
  12. {
  13. retunr dfs(n) ;
  14. }

Generatur arbor recursiva violenta recursionis

Ad quaestionem solvendam praedictam duplicationem in arbore recursiva, methodus inquisitionis scientificae adhiberi potest ad removendum magnum numerum arborum identicarum quae saepe constructae sunt, ita ut efficientiam calculi augeat. (imbricatis subproblems

Memoized quaero:

Computare omnes problematum sub-imbricationem semel tantum, debes declarare ordinatam nem ad solutionem uniuscuiusque quaestionis sub- notare, et sub- problemata per vestigationis processum imbricata putabis.

  1. Ubi dp[i] primum computatur, in nem[i] ad posteriorem usum refertur.
  2. Cum dp[i] iterum computatur, protinus in nem[i] fit, ne crebris problematum calculis.

Exemplum codicis:

  1. # python 代码示例
  2. def dfs(i : int, mem : list[int]) -> int :
  3. if i == 1 or i == 2 :
  4. return i
  5. if mem[i] != -1 :
  6. return mem[i]
  7. count = dfs(i - 1, mem) + dfs(i - 2, mem)
  8. # 记录dfs(i)
  9. mem[i] = count
  10. return count
  11. def climbing_stairs_dfs_mem(n : int) -> int :
  12. mem = [-1] * (n + 1)
  13. return dfs(n, mem)
  1. // c++ 代码示例
  2. int dfs(int i, vector<int> &mem)
  3. {
  4. if (i == 1 || i == 2)
  5. {
  6. return i ;
  7. }
  8. if (mem != -1)
  9. {
  10. return mem[i] ;
  11. }
  12. int count = dfs(i - 1, mem) + dfs(i - 2, mem) ;
  13. mem[i] = count ;
  14. return count ;
  15. }
  16. int climbingStairsDFSMem(int n)
  17. {
  18. vector<int> mem(n + 1, -1) ;
  19. return dfs(n, mem) ;
  20. }

Post memoizationem, omnes problematum sub- imbricati semel tantum computantur, et tempus multiplicitas optimized ad O (n).

Programmatio dynamica:

Investigatio motivata est methodus "top-ad-bottom". Ab problemate originali (nodi radicis) incipimus et majores problemata sub-reflexiva in problemata minora dissolvere donec minimas notae sub-nodi solvemus. . Postea solutiones ad problematum sub- ductae per iacum per cessionem colliguntur ad solutionem problematis originalis construendam.

E contra, programmatio dynamica est accessus "bottom-to-top": incipiens a solutione ad minima subproblem et itera- tive solutiones aedificandi ad ampliores problematum, donec solutio quaestionis originalis obtineatur.

Cum programmatio dynamica non includit processum regressum, solum opus est ut per ansam iteratio perficiatur sine recursione utendi.

Exemplum codicis: (programma dynamica, incipiens a minimo subprobrio)

  1. # python 代码示例
  2. def clibing_stairs_dp(n) :
  3. if n == 1 or n == 2 :
  4. return n
  5. dp = [0] * (n + 1)
  6. dp[1], dp[2] = 1, 2
  7. for i in range(3,n + 1) :
  8. dp[i] = dp[i-1] + dp[i- 2]
  9. return dp[n]
  1. // c++ 代码示例
  2. int climbingStairsDP(int n)
  3. {
  4. if (n == 1 || n == 2)
  5. {
  6. retunr n ;
  7. }
  8. vector<int> dp(n + 1, -1) ;
  9. dp[1] = 1 ;
  10. dp[2] = 2 ;
  11. for (int i = 3 ; i <= n ; i++)
  12. {
  13. dp[i] = dp[i - 1] + dp[i- 2] ;
  14. }
  15. return dp[n] ;
  16. }

Processus exsecutionis (programma dynamicus):

Analysis: (dynamica programmatio)

Similis algorithmus regressus, programmatio dynamica etiam conceptu "statis" utitur ad certum statum problema solvendum. Exempli gratia: Status quaestionis scalae ascensus definitur ordo i gradus currentis.

Ex praedictis, terminis communibus pro terminis dynamicis compendiari possumus:

  1. Ordinata dp dicta {dp table}, dp[i] solutionem sub- problemati statui i respondentem significat.
  2. Status correspondens minimo subprobli (primo et secundo gradibus) appellatur status initialis
  3. Formula recursiva dp[i] = dp[i-1] + dp[i-2] aequatio status appellatur.

Spatium ipsum:

dp[i] tantum ad dp[i-1] et dp[i-2] refertur.

Loco utendi ordinata ad solutiones ad omnes subproblem reponendas, sicut duae variabiles opus sunt ut librum deinceps.

Exemplum codicis:

  1. # python 代码示例
  2. def clibing_stairs_dp_comp(n) :
  3. if n == 1 or n == 2 :
  4. return n
  5. a, b = 1, 2
  6. for _ in range(3, n + 1) :
  7. a, b = b , a + b
  8. return b
  1. // c++ 代码示例
  2. int climbingStairsComp(int n)
  3. {
  4. if (n == 1 || n == 2)
  5. {
  6. return n ;
  7. }
  8. int a = 1 , b = 2 ;
  9. for (int i = 3 ; i <= n ; i++)
  10. {
  11. int temp = b ;
  12. b = a + b ;
  13. a = temp ;
  14. }
  15. return b ;
  16. }

Analysis:

Spatium ordinata dp omittitur, et spatium multiplicitas ab O(n) ad O(1) reducitur.

In programmandis quaestionibus dynamicis, status hodiernus solum ad paucitas priorum status se habet. . Hoc spatium optimization ars appellatur "variabilium volubilis" vel "volubilis vestitus".