NYOJ1058. 部分和问题(基础DFS)
2017-07-19 16:07
375 查看
部分和问题
时间限制: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
可以确定,k大于输入的n个数之和sum是一定无解的,因此在搜索前进行一步“剪枝”,可排除一种无解的情况。若sum<=k,则从前往后搜索,结合递归与回溯法的思想,寻找可能情况。需要注意的是,输出的解的n个数的所有排列是同一种情况,因此要做去重处理。
时间限制: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
可以确定,k大于输入的n个数之和sum是一定无解的,因此在搜索前进行一步“剪枝”,可排除一种无解的情况。若sum<=k,则从前往后搜索,结合递归与回溯法的思想,寻找可能情况。需要注意的是,输出的解的n个数的所有排列是同一种情况,因此要做去重处理。
#include <stdio.h> #include <string.h> #define maxn 25 int n,k; int a[maxn]; int vis[maxn],ret[maxn]; int suc,total; void dfs(int cur,int sum) { int i; if(sum>k) return; if(suc==1) return; if(sum==k) { printf("YES\n"); suc=1; for(i=0;i<cur-1;i++) printf("%d ",ret[i]); printf("%d\n",ret[cur-1]); return; } //从cur开始搜索即可,因保证从前向后 for(i=cur;i<n;i++) { if(!vis[i]) { if(sum+a[i]>k) continue; vis[i]=1; ret[cur]=a[i]; dfs(cur+1,sum+ret[cur]); vis[i]=0; } } } int main() { int i; while(scanf("%d %d",&n,&k)!=EOF) { for(i=0;i<n;i++) { scanf("%d",&a[i]); total+=a[i]; } if(total<k) printf("NO\n"); else { memset(vis,0,sizeof(vis)); suc=0; dfs(0,0); if(suc==0) printf("NO\n"); } } return 0; }
相关文章推荐
- nyoj1058部分和问题(简单基础易上手的dfs)
- NYOJ 1058 部分和问题 (DFS)
- NYOJ--1058--dfs--部分和问题
- NYOJ - 1058 - 部分和问题(DFS+减枝)
- 【经典DFS】NYOJ-1058-部分和问题
- NYOJ 1058 部分和问题 【DFS】
- nyoj 1058部分和问题(DFS)
- [DFS] NYOJ-1058-部分和问题
- NYOJ 1058 部分和问题(经典题目dfs)
- NYOJ 1058 部分和问题 (DFS)
- NYOJ 1058 部分和问题(dfs)
- NYOJ-1058- 部分和问题(DFS)
- NYOJ 1058 部分和问题(DFS)
- nyoj--1058--部分和问题(dfs)
- nyoj 1058 部分和问题 【DFS】
- NYOJ 1058 部分和问题(DFS ,经典题)
- NYOJ 1058 部分和问题 (深搜DFS)
- NYOJ1058 部分和问题(DFS)
- nyoj1058 部分和问题 dfs
- nyoj--1058 部分和问题(dfs)