4 13
1 2 4 7
YES
2 4 7
测试数据略水啊,我倒着将枚举数也过了。为了过的彻底,将n-1传到dfs函数中,这样记录下来的数组就是按照输入顺序来的了。不好意思,蒟蒻的dfs写的很怪异。
第一发,虽然NYOJ能过,但是错的,数据不严谨。例如: 4 9 1 3 5 6 或者 4 9 1 3 5 8
#include<cstdio> int a[22],n,k,num[22]; int t; bool dfs(int i,int sum) { if(sum>k) return false; if(i==n) return sum==k; if(dfs(i+1,sum)) return true; if(dfs(i+1,sum+a[i])) { num[t++]=a[i]; return true; } return false; } int main() { int i; while(scanf("%d%d",&n,&k)!=EOF) { for(i=0;i<n;++i) scanf("%d",&a[i]); t=0; if(dfs(0,0)) { printf("YES\n"); for(i=t-1;i>0;--i) printf("%d ",num[i]); printf("%d\n",num[i]); } else printf("NO\n"); } return 0; }
第二发,补了一下上面的漏洞,个人感觉没问题了(有问题请在评论指出),代码如下:
#include<cstdio> int a[22],n,k,num[22],sign[22]; int t; bool dfs(int i,int sum) { if(sum>k) return false; if(i==-1) return sum==k; if(dfs(i-1,sum)) return true; if(dfs(i-1,sum+a[i])) { num[i]=a[i]; sign[i]=1;//标记改下标对应的数是否在目标数列中 return true; } return false; } int main() { int i; while(scanf("%d%d",&n,&k)!=EOF) { for(i=0;i<n;++i) { scanf("%d",&a[i]); sign[i]=0; } if(dfs(n-1,0))//倒叙dfs { printf("YES\n"); for(i=0;i<n;++i) { if(sign[i]) { printf("%d",num[i]); break; } } for(i=i+1;i<n;++i) { if(sign[i]) printf(" %d",num[i]); } printf("\n"); } else printf("NO\n"); } return 0; }
再贴一发长木学长的吧,他写的好理解,比较正常,学习学习
#include <stdio.h> int n, k, ok, arr[22], vis[22], count; void DFS(int pos){ if(count >= k){ if(count == k){ if(!ok){ ok = 1; printf("YES\n"); } for(int i = 0; i < n; ++i) if(vis[i]) printf("%d ", arr[i]); printf("\n"); } return; } for(int i = pos; i < n; ++i){ count += arr[i]; vis[i] = 1; DFS(i + 1); count -= arr[i]; vis[i] = 0; } } int main(){ while(scanf("%d%d", &n, &k) == 2){ ok = 0; for(int i = 0; i < n; ++i){ scanf("%d", arr + i); vis[i] = 0; } count = 0; DFS(0); if(!ok) printf("NO\n"); } return 0; }