//在一个数组里 寻找任意个数的和为给定值
//这里输出所有的结果。
void PrintResult(int **dp,int data[],int length,int sum,list<int> &res);
void FindNumberofValueN(int data[],unsigned int length,int sum)
{
if(data == NULL || length == 0)
return;
int **dp = new int*[length+1];
for(int i = 0; i <= length; ++i)
dp[i] = new int[sum+1];
//行为数组data[i],列为和j
/*
//dp[i][j]表示在数组data的前i个数字里能找到和为j的几个数。
for(i = 0; i <= length; ++i)
{
for(int j = 0; j <= sum; ++j)
{
dp[i][j] = 0;
}
}
for(i = 0; i <= length; ++i)
{
dp[i][0] = 1;
}
dp[0][0] = 1;
for(i = 1; i <= length; ++i)
{
for(int j = 0; j <= sum; ++j)
{
if( j >= data[i-1])
{
dp[i][j] = dp[i-1][j-data[i-1]];
}
if(dp[i-1][j] == 1)
dp[i][j] = 1;
//dp[i][j] = 0;
}
}
*/
//dp[i][j]表示data[i]能作为和为j的一份子
//因为data[]是从下标1开始,所以下面用到的data[i]都要表示为Data[i-1]
for(i = 0; i <= length; ++i)
{
for(int j = 0; j <= sum; ++j)
{
dp[i][j] = 0;
}
}
// for(i = 0; i <= length; ++i)
// {
// dp[i][0] = 1;
// }
dp[0][0] = 1;
for(i = 1; i <= length; ++i)
{
for(int j = 0; j <= sum; ++j)
{
if( j >= data[i-1]) //这里看当和为j时, 该元素是否能作为一份子
{
bool flag = false;
for(int k = i - 1; k >= 0; --k)
{
if(dp[k][j-data[i-1]] == 1) //当该元素作为一份子里, 剩下的值j-data[i], 是否存在
{
flag = true;
break;
}
}
if(flag)
dp[i][j] = 1;
}
}
}
//输出dp[i][j]矩阵
for(i = 0; i <= length; ++i)
{
for(int j = 0; j <= sum; ++j)
{
cout<<dp[i][j]<<" ";
}
cout<<endl;
}
/*
//打印数字
for(int j = sum; j > 0;)
{
int i = 0;
//这里一定要把 i <= length 放在前面,要不然会越界错误
while(i <= length && dp[i][j] == 0)
++i;
if( i > length)
{
cout<<"Not Find!"<<endl;
return;
}
j = j -data[i-1];
cout<<data[i-1]<<" ";
}
cout<<endl;
*/
list<int> res;
res.clear();
PrintResult(dp,data,length,sum,res);
// cout<<endl;
for(i = 0; i <=length; ++i)
delete [] dp[i];
delete []dp;
}
void PrintResult(int **dp,int data[],int length,int sum,list<int> &res)
{
if(sum == 0 )
{
for(list<int>::iterator iter = res.begin(); iter != res.end();++iter)
{
cout<<*iter<<" ";
}
cout<<endl;
return;
}
int j = sum;
int i = length;
while(i > 0)
{
while(i > 0 && dp[i][j] == 0)
--i;
if(i == 0)
break;
// cout<<data[i-1]<<" ";
res.push_back(data[i-1]);
PrintResult(dp,data,i-1,j - data[i-1],res);
res.pop_back();
--i;
}
}
void main()
{
<span style="white-space:pre"> </span>int data[] = {11,5,6,1,2,3,4,10,12,30};
<span style="white-space:pre"> </span>int length = sizeof(data)/sizeof(int);
<span style="white-space:pre"> </span>int sum = 16;
<span style="white-space:pre"> </span>FindNumberofValueN(data,length,sum);
}
运行测试结果
<img src="https://img-blog.csdn.net/20140901151729386?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmludmNy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />