第五章作业

7-1 子集和问题 (50 分)

设集合S={x1,x2,…,xn}是一个正整数集合,c是一个正整数,子集和问题判定是否存在S的一个子集S1,使S1中的元素之和为c。试设计一个解子集和问题的回溯法。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int n,c,a[10000],b[10000],d[10000],i,sum=0;
bool pd;

void print(int dep)
{
int j;
for (j=1;j<=dep;++j)
printf("%d ",d[j]);
printf("\n");
return;
}

void dfs(int dep)
{
int r;
if (pd==1) return;//因为只需输出一组解,c++又没法结束整个程序
for (r=1;r<=n;++r)
if (!b[r]&&c-a[r]>=0)
{
if (pd==1) return;
c-=a[r];//用c减去每个数,其实就是几个数之和等于c
d[dep]=a[r];//d是记录数组
b[r]=1;
if (c==0) //如果找到一组解,直接输出,完成任务
{
if (pd==0)
print(dep);
pd=1;
return;
}
else dfs(dep+1);
if (pd==1) return;
c+=a[r];//回溯一步
b[r]=0;
}
}

int main()
{
scanf("%d%d",&n,&c);
for (i=1;i<=n;++i)
{
scanf("%d",&a[i]);
sum+=a[i];
}
if (sum<c)//剪枝,如果所有的数加起来都小于c,那么不可能有解。
{
printf("No solution!");
return 0;
}
memset(d,0,sizeof(d));
memset(b,0,sizeof(b));
pd=0;
dfs(1);
if (!pd) printf("No solution!");
return 0;
}

前面部分正确,等到subsume10就出错了,应该是循环里的顺序出错了,但是作业ddl快到了,先交再改吧

 

 

第二题还不会写。。。

posted on 2018-12-24 18:57  计科一俞崔雯  阅读(240)  评论(0编辑  收藏  举报