题目:输入两个整数n 和m,从数列1,2,3.......n 中随意取几个数,使其和等于m ,要求将其中所有的可能组合列出来.
1. 是01背包问题。从最大值n开始取, 如果取n ,则剩下的为 m-n.需要从剩下的n-1个数中取。 如果不取n,则和仍为m,从剩下的n-1个数中取。所以,会是一个递归问题。
find(m-n, n-1) 已确定有n
find(m,n): find(m, n-1) 已确定无n
递归一定要有结束条件
2. 保存已经取得的值。一般会用堆栈,当使用某个数开始,无法找到解时,清空栈。再从无这个数开始找。
3. 下面这个程序是从网上找到的普遍思路,问题在判断条件。if(sum <= n)时,先输出了sum,此sum就是还差的 那个值。(因为堆栈中时从大到小存放,此时,sum<n,也就是说,当前还差的值在1--n之间,)再输出堆栈中的所有值。即可找到解。
4. 通过递归,可以找到所有解
如sum=10, n=8, 会调用find(2,7),此,2<7,输出2,再输出8。通过递归调用,最终输出所有解。 2 8,3 7 ,4 6 ,1 5 4 ,2 5 3 ,1 4 3 2,
#include<iostream>
#include<list>
using namespace std;
list<int> listBag;
void findSum( int sum ,int n )
{
if ( n < 1 || sum < 1 )
return ;
if( sum > n )
{
listBag.push_back ( n ) ;
findSum( sum -n , n -1 );
listBag.pop_back();
findSum( sum , n-1 ) ;
}
else
{
cout << sum ;
list<int>::iterator it ;
it = listBag.begin();
for ( ;it != listBag.end() ; it ++ )
{
cout << (*it) ;
}
cout << endl;
}
}
void main()
{
findSum ( 10 , 8 );
system("pause");
}