拆数——搜索与回溯
题目描述 Description
求任何一个大于0的自然数n,总可以拆分成若干个小于n的自然数之和
输入输出格式 Input/output
输入格式:
一个正整数n
输出格式:
n=XXX+XXX+XXX+XXX…
一个正整数n
输出格式:
n=XXX+XXX+XXX+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
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 }
我不怕千万人阻挡,只怕自己投降…