【题目链接:NYOJ-1058

  看到题目难度是2,所以想也没想,直接循环比较。。。结果果然。。。 是错的。

 #include<cstdio>
#include<cstring>
int main(){
int n,k;
int i,j;
int a[] = {},num[] = {};
scanf("%d%d",&n,&k);
for(i = ;i < n;i++)
scanf("%d",&a[i]);
int ac = ,xx = ;
for(i = ;i < n;i++){
int sum = ;
for(j = i;j < n;j++){
sum += a[j];
num[xx] = a[j];
xx++;
if(sum == k){
ac = ;
break;
}
}
if(ac == )
break;
else{
xx = ;
memset(num,,sizeof(num));
}
}
if(ac){
printf("YES\n");
for(i = ;i < xx;i++)
printf("%d ",num[i]);
}else{
printf("NO");
}
return ;
}

  以上错误代码,就不回忆为啥错了。。。 贴这儿供着吧。

这题的正确思路是运用DFS

  详见:《挑战程序设计》 P30

 #include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
//部分和问题:
const int maxn = ;
stack<int>v;
int a[maxn];
int n,m,i,j,k;
bool dfs(int i = ,int sum = ) //已经从前i项得到了和sum,然后对于i项之后的进行分支
{
//停止条件 :如果前n项都计算过了,则返回sum是否与k相等
if(i==n) return sum==k;
//选择加或不加a[i]
//不加a[i]的情况
if(dfs(i+,sum)) return true;
//加上a[i]的情况
if(dfs(i+,sum+a[i])){
//若执行该条件,就说明该a[i]符合条件
v.push(a[i]);//压栈
return true;
}
return false; //无论是否加上a[i]都不能凑成k就返回false;
}
int main(){
while(~scanf("%d%d",&n,&k)){
for(int i = ;i < n;i++){
scanf("%d",&a[i]);
}if(dfs()){
printf("YES\n");
while(!v.empty()){
int x = v.top();
printf("%d ",x);
v.pop();
}
printf("\n");
}else
printf("NO\n");
}
return ;
}

  优化:

    1.当然也可以用数组代替栈,时间消耗会短8个。

    2.在状态转移时,如果sum > k,则不需要继续进行了。

    (因为是递归,递归的机制就是从上到下,再从下到上返回,所以数组保存的顺序是反向的)

  优化代码:

 #include<cstdio>
#include<stack>
using namespace std;
stack<int>v;
const int maxn = ;
int a[maxn];
//int sta[maxn];
int n,m,k,pos;
bool dfs(int i,int sum){
if(i==n) return sum==k;
else if(sum > k) return false; //剪枝(这么专业的名词也不知道用的对不对,反正就是优化了一下)
if(dfs(i+,sum)) return true;
if(dfs(i+,sum+a[i])){
//sta[pos++] = a[i];
v.push(a[i]);
return true;
}
return false;
}
int main(){
while(~scanf("%d%d",&n,&k)){
pos = ;
for(int i = ;i < n;i++){
scanf("%d",&a[i]);
}if(dfs(,)){
printf("YES\n");
// for(int i = pos - 1;i >= 0;i--)
// printf("%d ",sta[i]);
while(!v.empty()){
printf("%d ",v.top());
v.pop();
}
printf("\n");
}else
printf("NO\n");
}
return ;
}

    

  

【经典DFS】NYOJ-1058-部分和问题的更多相关文章

  1. nyoj 1058部分和问题(DFS)

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

  2. NYOJ 1058 部分和问题 【DFS】

    部分和问题 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描写叙述 给定整数a1.a2........an,推断能否够从中选出若干数.使它们的和恰好为K. 输入 首先,n和k ...

  3. NYOJ 1058 部分和问题

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

  4. 洛谷 P1019 单词接龙【经典DFS,温习搜索】

    P1019 单词接龙 题目描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在 ...

  5. nyist oj 1058 部分和问题 (DFS搜索)

    部分和问题 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描写叙述 给定整数a1.a2........an.推断能否够从中选出若干数,使它们的和恰好为K. 输入 首先,n和k ...

  6. NYOJ之题目1058部分和问题

    ---------------------------------------- 简单搜索+剪枝 因为考虑到可能会有多个解,所以是将中间过程保存最后才一起打印出来的 AC代码: 1: 2: impor ...

  7. 经典DFS问题实践

    八皇后问题: //八皇后问题 经典的DFS问题实践 #include<iostream> #include<cmath> #include<algorithm> # ...

  8. HDU 1016 Prime Ring Problem(经典DFS+回溯)

    Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  9. HDU 2181 哈密顿绕行世界问题(经典DFS+回溯)

    哈密顿绕行世界问题 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

随机推荐

  1. android.os.DeadObjectException memory near r0: 异常处理 Consumer closed input channel or an error occurred. events=0x9

    原地址:http://www.cnblogs.com/wanqieddy/p/3495338.html android.os.DeadObjectException memory near r0: 异 ...

  2. 【redis】06Redis的高级应用之事务处理、持久化操作、pub_sub、虚拟内存

    上节课详细讲解了redis数据库的常用命令,以及redis数据库高级应用当中的, 安全性,跟咱们的主从复制, 这节课呢,咱们继续来讲咱们的高级应用, 首先来看一下咱们的事务处理, 事务处理 我前面说过 ...

  3. Android 异步加载

    Android 4.0 后 貌似规定了 在主线程中不允许访问网络,在子线程中不允许修改UI. 否则会抛出NetworkOnMainThreadException 异常 解决办法: 采用继承 Async ...

  4. java打印时间精确到毫秒

    package net.floodlightcontroller.conflict; import java.io.*; import java.util.*; import java.text.Si ...

  5. 【PHP高效搜索专题(1)】sphinx&Coreseek的介绍与安装

    我们已经知道mysql中带有"%keyword%"条件的sql是不走索引的,而不走索引的sql在大数据量+大并发量的时候,不仅效率极慢还很有可能让数据库崩溃.那我们如何通过某些关键 ...

  6. MIT算法导论——第一讲.Analysis of algorithm

    本栏目(Algorithms)下MIT算法导论专题是个人对网易公开课MIT算法导论的学习心得与笔记.所有内容均来自MIT公开课Introduction to Algorithms中Charles E. ...

  7. iOS视频录制、压缩导出、取帧

    概述 花了点时间研究了一下常用的视频获取.录制.压缩.取帧图功能,分享给大家了!相信阅读完本篇文章,会对你有很大的帮助的! 本篇文章研究几下以个功能: 视频录制 从相册选择视频 保持视频到相册 获取视 ...

  8. import java.util.Scanner;

    一.扫描控制台输入     当通过new Scanner(System.in)创建一个Scanner,控制台会一直等待输入,,,,,,,直到敲回车键结束,把所输入的内容传给Scanner,作为扫描对象 ...

  9. 获取其它进程窗口中的状态栏信息(FindWindowEx GetWindowThreadProcessId OpenProcess SendMessage轮番轰炸)

    HWND hWnd = ::FindWindow(NULL, _T("XXXXX")); if(NULL == hWnd) { return ; } HWND hWndStatus ...

  10. iOS xcuserdata

    说明:       project.xcworkspace说明:is a directory of files describing the workspace or projects. Althou ...