子集和问题
题目描述
对于一个给定正整数的集合s={x1,x2,x3…xn}和正整数c,编程计算s的第一个子集s1,使得子集s1的和等于c。
输入
第一行有2个正整数n和c
第二行有n个正整数
n<7000,c<maxlongint
第二行有n个正整数
n<7000,c<maxlongint
输出
一行数据,按输入的顺序输出,若无解则输出"No Solution!"
样例输入
5 10
2 2 6 5 4
样例输出
2 2 6
提示
这道题需要剪枝才能AC,剪枝方法是计算出后缀和数组sum[i]和最小值数组mina[i].在进行枚举时增加逻辑如下:如果当前已选中元素和加上sum[i]小于c,或者当前已选中元素和加上mina[i]大于c,直接返回即可。
#include<cstdio>#include<algorithm>using namespace std;long long n,m,ans[7001],a[7001],sum[7001],minn[70001];bool chu=0;void dfs(int k,int chang,int he){ if(he==m) { for(int i=0;i<chang;i++) { printf("%d ",ans[i]); } chu=1; return; } if((k==n||he+sum[k]<m||he+minn[k]>m)) return; if(chu==1) return; if(he+a[k]<=m) { ans[chang]=a[k]; dfs(k+1,chang+1,he+a[k]); } dfs(k+1,chang,he);}int main(){ scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%d",&a[i]); } sum[n-1]=a[n-1];minn[n-1]=a[n-1]; for(int i=n-2;i>=0;i--) { sum[i]=a[i]+sum[i+1]; minn[i]=1000000000; minn[i]=min(minn[i+1],a[i]); } dfs(0,0,0); if(chu==0) { printf("No Solution!"); }}

浙公网安备 33010602011771号