您的位置:首页 > 编程语言 > C语言/C++

子集和问题 及 c++ 代码实现

2013-06-14 17:03 260 查看
   首先声明:子集和问题可以用动态规划问题解决,即01背包问题的解法即可。在这里我们采用下构造树的问题。

问题:

      给定n个正整数{wi|i=0...n}和一个正整数m,在这n个正整数中找出一个子集,使得子集中的正整数之和等于m。

 

解的形式:

      设定一个n元组(x0,x1,...xn-1),如果wi包含在这个子集中,x是解向量,xi就等于1,反之等于0.

X数组是解向量,t=∑(1,..,k-1)Wi*Xi, r=∑(k,..,n)Wi    (说明:t就是前k-1个数选择之后的和,r表示剩余n-k+1个数的和)

若t+Wk+W(k+1)<=M,则Xk=true,递归左儿子(X1,X2,..,X(k-1),1);否则剪枝;

若t+r-Wk>=M && t+W(k+1)<=M,则置Xk=0,递归右儿子(X1,X2,..,X(k-1),0);否则剪枝;

本题中W数组就是(1,2,..,n),所以直接用k代替WK值。

 

算法伪代码:(这边的s为分析中的t,r为上述分析中的r)



C++ 代码实现

#include<iostream>
#include<cstdlib>
using namespace std;

void findSubSum(int m,int k,int st,int res,int *x)   //m表示为和,st表示前k个元素,res表示剩下数的总和,x表示解向量     
{
x[k]=1;
if(m==st+k)
{
for(int i=1;i<=k;i++)
if(x[i]==1)
cout<<i<<" ";
cout<<endl;
}
else if(st+k+k+1<=m)
findSubSum(m,k+1,st+k,res,x);

if((m<=st+res-k)&&(st+k+1<=m))
{
x[k]=0;
findSubSum(m,k+1,st,res-k,x);
}
}

void subSum(int m,int n)
{
int *x=new int[n+1]();
int sum=(n+1)*n/0.5;
if(m<0||m>sum)
{
cout<<"bad num m:there is no result"<<endl;
return;
}

findSubSum(m,1,0,sum,x);
free(x);
}
int main()
{
int m,n;
cout<<"please input the list number(N):"<<endl;
cin>>n;
cout<<"please input the sum number(M):"<<endl;
cin>>m;
subSum(m,n);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ 算法