您的位置:首页 > 其它

nyoj 1058 部分和问题(dfs+剪枝)

2017-03-22 18:51 225 查看

部分和问题

时间限制:1000 ms  |  内存限制:65535 KB
难度:2
描述 给定整数a1、a2、.......an,判断是否可以从中选出若干数,使它们的和恰好为K。
输入首先,n和k,n表示数的个数,k表示数的和。

接着一行n个数。

(1<=n<=20,保证不超int范围)输出如果和恰好可以为k,输出“YES”,并按输入顺序依次输出是由哪几个数的和组成,否则“NO”样例输入
4 13
1 2 4 7

样例输出
YES
2 4 7


分析:dfs求解。

AC代码:

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=20+2;
int a[maxn];
int path[maxn];
int n,k;

int dfs(int i,int cur,int sum){//对应员数组位置i,路径记录当前位置cur,当前总和sum
int ans=0;
if(sum==k){
printf("YES\n");
printf("%d",path[1]);
for(int i=2;i<cur;i++)
printf(" %d",path[i]);
printf("\n");
return 1;
}

if(sum>k)return 0; //剪枝

for(int j=i+1;j<=n;j++){
path[cur]=a[j];
ans=dfs(j,cur+1,sum+path[cur]);
if(ans)return 1;
}
return ans;
}
int main(){
while(scanf("%d%d",&n,&k)==2){
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);

int flag;
for(int i=1;i<=n;i++){
path[1]=a[i];
flag=dfs(i,2,a[i]);
if(flag)break;
}
if(!flag)printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: