1. 程式人生 > >遞歸or動態規劃 百煉 2749 分解因數 詳細題解

遞歸or動態規劃 百煉 2749 分解因數 詳細題解

out 數量 ostream 記錄 有一個 queue crt 數據 warn

 1 #define _CRT_SECURE_NO_WARNINGS  
 2 #include <stdio.h>
 3 #include <math.h>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 #include <vector>
 7 #include <map>
 8 #include <queue>
 9 #include <string>
10 #include <iostream>
11 #include <ctype.h>
12
#include <string.h> 13 #include <set> 14 #include <stack> 15 #include<functional> 16 using namespace std; 17 #define Size 22 18 #define maxn 1<<30 19 #define minn 1e-6 20 int dp[Size][Size]; 21 /* 22 定義dp[i][j] 表示將i分解成不大於j的因數的個數 23 24 i如果能分解出來j,即為i%j==0; 那麽其可以由兩種互斥的情況組成,
25 1,如果最終的劃分結果有至少一個j 那麽其種類數為dp[i/j][j](註意下次最大劃分數仍是j,表示下一次仍然可以劃分出 j,如果要求分解的每個數不重復,那麽改為dp[i/j][j-1]即可) 26 2,如果最終的劃分結果連一個j都沒有,那麽其種類數為dp[i][j-1] 27 比如 8%2==0 dp[8][2]=dp[4][2]+dp[8][1] 28 前面的是至少有一個2(然後把這個2劃分出去,剩下的部分組合的數量是dp(4,2)) 29 後面的是沒有劃分出2(那麽劃分出來最大的數就是1) 30 31 i如果不能分解j,即為i%j!=0 那麽dp[i][j]=dp[i][j-1]
32 總結 33 if(i%j==0) 34 dp[i][j]=dp[i][j-1]+dp[i/j][j]; 35 else 36 dp[i][j]=dp[i][j-1]; 37 38 然後尋找出口 39 1,if(j>i) dp[i][j]=dp[i][i] 40 2,dp[1][1]=dp[1][0]+dp[1][1] 41 3,dp[2][2]=dp[2][1]+dp[1][1]=1 42 根據上面兩行推導出dp(2,1)=0 dp[1,1]=1 可以推導if(i>1) dp(i,1)=0 43 總結得到出口條件 44 i==1 return1 45 j==1 return0 46 註意上面兩行是有順序的如果顛倒就出錯了 47 */ 48 int solve(int i, int j){//本題數據量太小 ,不用記錄狀態,遞歸即可直接A 49 if (i == 1) return 1; 50 if (j == 1) return 0; 51 if (i%j == 0) return solve(i / j, j) + solve(i, j - 1); 52 return solve(i, j - 1); 53 } 54 int main() 55 { 56 int n; 57 cin >> n; 58 while (n--){ 59 int x; 60 cin >> x; 61 int ans = solve(x, x); 62 cout << ans << endl; 63 } 64 return 0; 65 }

遞歸or動態規劃 百煉 2749 分解因數 詳細題解