【题目链接: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面试题基础(转)

    71道经典Android面试题和答案 1.下列哪些语句关于内存回收的说明是正确的? (b ) A. 程序员必须创建一个线程来释放内存 B.内存回收程序负责释放无用内存 C.内存回收程序允许程序员直接释 ...

  2. java中的freopen

    在做ACM题目的时候,为节省输入测试数据的时间,我们通常将数据复制到一个文本文档里,然后从文档里读出,避免在控制台一个数据一个数据的输入. 之前一直用的C/C++,freopen用起来很方便,如下: ...

  3. lintcode :Segmemt Tree Build II

    题目 Segmemt Tree Build II The structure of Segment Tree is a binary tree which each node has two attr ...

  4. Hibernate逍遥游记-第5章映射一对多-01单向<many-to-one>、cascade="save-update"、lazy、TransientObjectException

    1. <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hi ...

  5. React Jest测试

    一. var jest = require('jest'); jest.dontMock('../CheckboxWithLabel.js'); describe('CheckboxWithLabel ...

  6. MSSQL2005数据库自动备份问题(到同一个局域网上的另一台电脑上)

    有A数据库服务器,B本机:    我现在想通过在B机器上通过代码调用SQL来执行A数据库的备份到B机器上    调用的SQL语句为:Backup Database MYDATABASE To Disk ...

  7. 44. Wildcard Matching

    题目: Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single charact ...

  8. android sqlite支持的数据类型

    Sqlite3支持的数据类型 :NULL.INTEGER.REAL.TEXT.BLOB 但实际上,sqlite3也接受如下的数据类型:    smallint 16 位元的整数.    interge ...

  9. The type xxx cannot be resolved. It is indirectly referenced from required .class files

    项目A中引入一个jar包B,在项目A中调用项目B,出现如下错误提示:   大致意思是:这上面所需的包是间接引用的,即A项目调用B项目,B项目又引用了另外一个包C,而这个包现在不在你的A项目的引用中. ...

  10. 将Ftp添加到资源管理器中直接使用

    在资源管理器中,右键,添加网络位置. 然后输入ftp的url ftp://server2008 使用匿名方式登录