部分和问题
时间限制:
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
-
int num[20]; long n, K; int flag; bool vis[20]; bool dfs(long sum, int cnt) { if(cnt == n){ //末端 return sum == K; //判断sum 是否等于 K } vis[cnt] = false; // 不加则为false if(dfs(sum, cnt+1)){ //不加num[i] return true; } vis[cnt] = true; //加上则为true if(dfs(sum + num[cnt], cnt+1)){ //加num[i] return true; } return false; }
#include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cctype> #include<cmath> #include<ctime> #include<string> #include<stack> #include<deque> #include<queue> #include<list> #include<set> #include<map> #include<cstdio> #include<limits.h> #define MOD 1000000007 #define fir first #define sec second #define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin) #define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout) #define mes(x, m) memset(x, m, sizeof(x)) #define Pii pair<int, int> #define Pll pair<ll, ll> #define INF 1e9+7 #define inf 0x3f3f3f3f #define Pi 4.0*atan(1.0) #define lowbit(x) (x&(-x)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define max(a,b) a>b?a:b typedef long long ll; typedef unsigned long long ull; const double eps = 1e-9; const int maxn = 22; const int maxm = 10000005; using namespace std; inline int read(){ int x(0),f(1); char ch=getchar(); while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); return x*f; } int num[maxn]; bool vis[maxn]; int n,k; bool flag; void dfs(int cnt,int sum){ if((cnt==n+1&&sum!=k)||sum>k){ //越界或者超过k return; } if(sum==k){ //输出 puts("YES"); for(int i=1;i<=n;++i){ if(vis[i]){ printf("%d ",num[i]); } } printf("\n"); flag=true; return; } if(flag){ //只判断一组答案即可 return; } for(int i=cnt;i<=n;++i){ //直接从cnt开始枚举 if(!vis[i]){ vis[i]=true; sum+=num[i]; dfs(i+1,sum); sum-=num[i]; vis[i]=false; } } } int main(){ // fin; while(~scanf("%d%d",&n,&k)){ flag=false; mes(vis,flag); for(int i=1;i<=n;++i){ scanf("%d",num+i); } dfs(1,0); if(!flag){ puts("NO"); } } return 0; }
-
首先,n和k,n表示数的个数,k表示数的和。