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 }