2 条题解
-
2
#include<iostream> using namespace std; int a[50]={0},k=1,sum=0; void f(int x){ if(x==0){//每轮拆分结束,输出方案并计数 for(int i=1;i<k-1;i++) cout<<a[i]<<'+'; cout<<a[k-1]<<endl; sum++; return; } for(int i=a[k-1];i<=x;i++){//以拆分序列的末尾元素a[k-1]为搜索起点,避免拆分重复 a[k++]=i;//拆分,入栈 f(x-i);//进入下一层拆分 k--;//弹出栈顶元素 } } int main(){ int n; a[0]=1;//第一次拆分为空栈,初始化搜索起点 cin>>n; f(n);//回溯搜索 cout<<"total="<<sum; return 0; }
-
2
#include <bits/stdc++.h> using namespace std; int a[10001]={1},n,total=1; int search(int,int); int print(int); int main() { cin>>n; search(n,1); //将要拆分的数传递给s cout<<n<<endl; //输出拆分的方案总数 cout<<"total="<<total<<endl; return 0; } int search(int s,int t) //搜索主函数 { int i; for(i=a[t-1];i<=s;i++) { if(i<n) //由于要求从小到大排数,所以当前数i要大于等于前一位数,且不超过n { a[t]=i; //保存当前拆分的数i s-=i; //s减去数i,s的值将继续被拆分而减小 if(s==0) print(t);//当s=0时,拆分结束输出结果 else search(s,t+1);//当s不为0时,即还没有拆分完时,递归继续拆分 s+=i; //回溯:加上拆分的数,以便产生所有可能的拆分 } //疑问:s的值是在递归之后复原的,为什么能回溯? } //思考:当递归推到边界时,栈会弹出,然后s的值复原,开始回溯搜索 } int print(int t) { for(int i=1;i<=t-1;i++) //输出一种拆分方案 cout<<a[i]<<"+"; cout<<a[t]<<endl; total++; //方案数累加1 }
例题,但是对于初学很难理解,所以写一下啦 珍爱生命,禁止抄袭
- 1
信息
- ID
- 420
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 4
- 标签
- 递交数
- 62
- 已通过
- 28
- 上传者