输入两个整数 n 和 m,从数列1,2,3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来
输入描述:
每个测试输入包含2个整数,n和m
输出描述:
按每个组合的字典序排列输出,每行输出一种组合
示例1
输入
5 5
输出
1 4 2 3 5
这道题就是一道典型的动态规划问题了,思路和背包问题差不多,m就相当于背包能容纳的重量了,就是从右往左校验,通过m,以及m-n进行下一次
也就是当前是GetFunc(m,n)那接下来就是进行GetFunc(m,n-1)和printList(m-n,n-1)进行递归
而终止条件是n<=0,以及m<0(m<0说明在上一次递归调用是减的n(相对于当前应该为n+1)是减多了,为负),m==0时候说明正好找到,打印
#include <iostream>
#include <vector>
using namespace std;
//这道题是一个典型的背包问题
//通过搜索,分为两种情况:选择、不选择
//如果选择当前值,那么背包空间和val都需要加到背包
//如果不选择,那么背包就是上一次的
//
//递归退出条件:m = 0,表示当前背包里面恰好就是结果,需要打印
//m<0,表示当前背包已经不足,所以背包里面数字并不满足要求
//start > n表示一轮遍历完毕
void GetFunc(int start,int n,int m,vector<int> v)
{
//n:从1到n个数字
//m:表示背包空间
if(m == 0)
{
for(int i =0;i<v.size();++i)
i == 0 ? cout<<v[i]:cout<<" "<<v[i];
cout<<endl;
return;
}
if(m < 0 || start>n)
return;
//要
v.push_back(start);
GetFunc(start+1,n,m-start,v);
//不要
v.pop_back();
GetFunc(start+1,n,m,v);
}
int main()
{
int n,m;
while(cin>>n>>m)
{
vector<int> v;
int start = 1;
GetFunc(start,n,m,v);
}
return 0;
}