1 #include<iostream>
2 using namespace std;
3
4 //打印一种划分
5 void display(int *result, int length)
6 {
7 cout << result[0];
8 for (int i = 1; i < length; i++)
9 {
10 cout << '+' << result[i];
11 }
12 cout << endl;
13 }
14
15 //fun: 可以输出表达式,还可以计算出表达式的个数
16 //n为待划分整数,m为最大加数上限;
17 //递归解法:将divide分为五种情况讨论;设 f(n,m) 为 n 的 m 划分个数
18 int divide(int n, int m, int *result, int length)
19 {
20 // n >= 0 && m == 1时,有n中{1,1,....1}.即划分为f(n-1,m); 如:6 = 1+1+1+1+1+1时
21 if (n >= 0 && m == 1)
22 { //直至(n == 0), 且m == 1时输出.
23 if (n == 0)
24 display(result, length);
25 else
26 {
27 result[length] = 1; //否则将拆分的表达式写到result中
28 divide(n-1, m, result, length+1); //递归添加
29 }
30 return 1; //相当于一次拆分的表达式
31 }
32
33 //当 n == 1 && m > 1时(待拆分数为1-相当于拆分完毕,且最大加数上限大于1),进行输出; 如: 4+2+1时
34 else if (n == 1 && m > 1)
35 {
36 result[length] = n;
37 display(result, length+1);
38 return 1; //返回1种划分可能
39 }
40
41 //当 n < m时(拆分数n < 最大加数上限m),由于没有负数划分(即将最大上限m换成n)就相当于f(n,n);
42 else if (n < m)
43 return divide(n, n, result, length);
44
45 //当 n == m时, 分为: 1.包含n时,只有 {n};
46 //2.不包含n时, 划分中最大数字一定比 n 小,即 n 的所有n-1划分。综上:f(n,n) = f(n, m-1) + 1;
47 else if (n == m)
48 {
49 result[length] = m; //添加划分
50 display(result, length+1); //输出划分
51 return divide(n, n-1, result, length) + 1 ; //递归
52 }
53
54 //当 n > m > 1时,分为: 1. 包含m时, {m, {x1,x2,..xi}}, {x1,..xi}的和为n-m,即为f(n-m,m)划分-调用了n<m条件的情况
55 //2. 不包含m时, 即划分中的所有值都比 m 小, 即 n 的 m-1 划分 f(n, m-1);
56 //综上: f(n,m) = f(n-m, m) + f(n, m-1);
57 else {
58 result[length] = m;
59 return divide(n-m, m, result, length+1) + divide(n, m-1, result, length);
60 }
61 }
62
63 int main(void)
64 {
65 const int maxn = 1010;
66 int n, buf[maxn], length = 0;
67 cin >> n;
68 divide(n, n-1, buf, length); //f(n,n-1)的划分
69
70 return 0;
71 }