拆数——搜索与回溯

题目描述 Description

求任何一个大于0的自然数n,总可以拆分成若干个小于n的自然数之和
 输入输出格式 Input/output
输入格式:
一个正整数n
输出格式:
n=XXX+XXX+XXX+XXX…
total(总方案数)=XXX
输入输出样例 Sample input/output
样例测试点#1
输入样例:
7
输出样例:
7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+2+2
7=1+1+1+4
7=1+1+2+3
7=1+1+5
7=1+2+2+2
7=1+2+4
7=1+3+3
7=1+6
7=2+2+3
7=2+5
7=3+4
total=14
思路:代码里已经给得十分清楚了,这里我就不多说了。。。
代码如下(本代码来自“《算法竞赛入门经典》 第5章 搜索与回溯算法C++版 标准代码”):
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstdlib>
 4 using namespace std;
 5 int a[10001]={1},n,total;
 6 int search(int,int);
 7 int print(int);
 8 int main()
 9 {
10     cin>>n;
11     search(n,1);                             
12          //将要拆分的数n传递给s
13     cout<<"total="<<total<<endl; 
14          //输出拆分的方案数
15     return 0;
16 }
17 int search(int s,int t)
18 {
19     int i;
20     for (i=a[t-1];i<=s;i++)
21     if(i<n)//当前数i要大于等于前1位数,且不过n(如果刚好等于n的话,加数中必定有一个为0,不合法!) 
22     {
23        a[t]=i;//递增 
24        //保存当前拆分的数i
25        s-=i;            
26        //s减去数i, s的值将继续拆分
27        if (s==0) print(t);                    
28        //当s=0时,拆分结束输出结果
29          else search(s,t+1);                  
30        //当s>0时,继续递归
31        s+=i;                                  
32        //回溯:加上拆分的数,以便产分所有可能的拆分
33     }
34 }
35 int print(int t)
36 {
37     cout<<n<<"=";
38     for (int i=1;i<=t-1;i++)                      
39     //输出一种拆分方案
40       cout<<a[i]<<"+";
41     cout<<a[t]<<endl;
42     total++;                                  
43    //方案数累加1
44 }

 

posted @ 2015-05-03 16:59  Memoryヾノ战心  阅读(264)  评论(0编辑  收藏  举报