整数划分问题

 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 }

 

posted @ 2016-06-26 11:54  douzujun  阅读(561)  评论(0编辑  收藏  举报