2 条题解

  • 2
    @ 2023-10-29 0:07:45
    #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
      @ 2022-11-15 20:41:33
      #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
      上传者