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

部分和问题

时间限制: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;
}



展开阅读全文

没有更多推荐了,返回首页