4004:数字组合||子集和数

来源:互联网 发布:幻想武器知乎 编辑:程序博客网 时间:2024/05/16 06:05

4004:数字组合

  • 查看
  • 提交
  • 统计
  • 提问
时间限制: 
1000ms
 
内存限制: 
65536kB
描述
有n个正整数,找出其中和为t(t也是正整数)的可能的组合方式。如:
n=5,5个数分别为1,2,3,4,5,t=5;
那么可能的组合有5=1+4和5=2+3和5=5三种组合方式。
输入
输入的第一行是两个正整数n和t,用空格隔开,其中1<=n<=20,表示正整数的个数,t为要求的和(1<=t<=1000)
接下来的一行是n个正整数,用空格隔开。
输出
和为t的不同的组合方式的数目。
样例输入
5 5 
1 2 3 4 5
样例输出
3



实验源码(OpenJudge通过)
#include"stdio.h" 

int n, M;
int w[20]={0};
int x[20]={0};
int count=0;
void sub(int s,int k, int r){

x[k] = 1;
if(s+w[k]==M)
count++;
else
{
if(s+w[k]+w[k+1]<=M&& k<n-1)
sub(s+w[k],k+1,r-w[k]);
}//可变长的树结构
 if((s+r-w[k]>=M)&&(s+w[k+1]<=M)&&k<n-1)
  {
x[k] = 0;
sub(s,k+1,r-w[k]);
}//相当于二叉树的右分支
}

int main()
{
int i,j,r,temp;
scanf("%d%d",&n,&M);
r=0;
for(i=0;i<n;i++)
{
scanf("%d",&w[i]);
r+=w[i];
}
for(i=1;i<n;i++)
{
j=i-1;
temp=w[i];
while(temp<w[j]&& j>=0)
{
w[j+1]=w[j];
j--;
}
w[j+1]=temp;
}//进行从小到大排序
sub(0,0,r); 
printf("%d\n",count); //解的个数
return 0;
}
原创粉丝点击