A Math game

Time Limit: 2000/1000MS (Java/Others) Memory Limit: 256000/128000KB (Java/Others)

Problem Description

Recently, Losanto find an interesting Math game. The rule is simple: Tell you a number H, and you can choose some numbers from a set {a[1],a[2],......,a[n]}.If the sum of the number you choose is H, then you win. Losanto just want to know whether he can win the game.

Input

There are several cases.
In each case, there are two numbers in the first line n (the size of the set) and H. The second line has n numbers {a[1],a[2],......,a[n]}.0<n<=40, 0<=H<10^9, 0<=a[i]<10^9,All the numbers are integers.

Output

If Losanto could win the game, output "Yes" in a line. Else output "No" in a line.

Sample Input

10 87
2 3 4 5 7 9 10 11 12 13
10 38
2 3 4 5 7 9 10 11 12 13

Sample Output

No
Yes

Source

第九届北京化工大学程序设计竞赛

DFS:

#include<bits/stdc++.h>
using namespace std;
const int N=;
int a[N],s[N], n, flag, h;
void dfs(int sum, int now)//sum是当前累加和,now是当前累加了几个数
{
if(sum == h){
flag = ; return ;
}
/*
1. flag==1 当前累加和为h,标记后直接退出
2. now == n + 1 不管能不能凑到h,累加的数次已经用完了
3. s[n] - s[now - 1] + sum < h 当前累加和+之前区间和也达不到h
4. sum > h 当还没到头当前累加和超过了h ,之后也只能超过 h,米有再搜索的必要了
*/
if(flag || now == n + || s[n] - s[now - ] + sum < h || sum > h){
return ;
}
dfs(sum+a[now],now+);//加当前这个数
dfs(sum,now+);//不加当前的数
}
int main()
{
while(cin >> n >> h)
{
for(int i=; i<=n; i++){
cin >> a[i];
s[i] = s[i-] + a[i];
}
flag = ;
dfs(,);
puts(flag?"Yes":"No");
}
return ;
}

折半查找:

/*
给定n个数字,问能否使这些数字相加得到h?
*/
/*
折半查找,先将前半部分的和算出来存在数组中,再将后半部分的数ans进行计算,然后在前半部分进行查找h-ans
这一题用到了一种新的写法,位运算。
用二进制来表示哪些数取了,哪些数没取。
比如,算前5个数字,2^5的二进制就是100000 那么可以把前面五个数的组合情况全部都表示出来
每一个二进制位表示第几个数,比如取第一和第三个数,那么二进制就是000101。
*/
#include<bits/stdc++.h>
using namespace std;
const int N=;
int a[N],sum[N];
int main()
{
int n, h, s;
while(cin >> n >> h)
{
for(int i=; i<n; i++)
cin >> a[i];
int k = , mid =( n >> );
for(int i=; i<(<<mid); i++)
{
s = ;
for(int j=; j<mid; j++)
{
if(i&(<<j)){
s += a[j];
}
}
if(s <= h) sum[k++] = s;//将前半部分的和算出来存在数组
} sort(sum, sum+k); int res = n - mid;
int f = ; for(int i=; i<(<<res); i++)
{
s = ;
for(int j=; j<res; j++)
{
if(i&(<<j)) s += a[mid + j]; //进行计算后半部分的数s
}
if(s > h) continue;
if(sum[lower_bound(sum,sum+k,h-s)-sum] == h - s) //将后半部分的数s进行计算,然后在前半部分进行查找h-s
{
f = ;
break;
}
}
puts(f?"Yes":"No");
}
return ;
}

给定n个数字,问能否使这些数字相加得到h【折半查找/DFS】的更多相关文章

  1. POJ1228:Grandpa's Estate(给定一些点,问是否可以确定一个凸包)

    Being the only living descendant of his grandfather, Kamran the Believer inherited all of the grandp ...

  2. 和安全有关的那些事(非对称加密、数字摘要、数字签名、数字证书、SSL、HTTPS及其他)

    转自http://blog.csdn.net/bluishglc/article/details/7585965 对于一般的开发人员来说,很少需要对安全领域内的基础技术进行深入的研究,但是鉴于日常系统 ...

  3. jQuery 判断是否为数字的方法 及 转换数字函数

    <script language="javascript"> var t=$("#id").val();//这个就是我们要判断的值了 if(!isN ...

  4. bitMap算法实现以及ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串

    ckHash函数类,将字符串映射成数字,同时可以将数字映射成字符串 说明 1.所谓的BitMap就是用一个bit位来标记某个元素所对应的value,而key即是该元素,由于BitMap使用了bit位来 ...

  5. 计算机二级-C语言-字符数字转化为整型数字。形参与实参类型相一致。double类型的使用。

    //函数fun功能:将a和b所指的两个字符串分别转化成面值相同的整数,并进行相加作为函数值返回,规定只含有9个以下数字字符. //重难点:字符数字转化为整型数字. #include <stdio ...

  6. isNaN() 函数用于检查其参数是否是非数字值。如果是非数字值则返回true

    isNaN() 函数用于检查其参数是否是非数字值.如果是非数字值则返回true.document.write(isNaN(0)); falsedocument.write(isNaN("He ...

  7. 一串数字中,只有一个数字出现一次,其他数字都出现两次,查找出这个数字(python)(原创)

    背景: 电话面试&手撕代码 2019.03.22 Mufasa 问题: 一串数字中,只有一个数字出现一次,其他数字都出现两次,查找出这个数字 条件: 这串数字是有序数 解决方法: 核心代码只有 ...

  8. 在Xshell 6开NumLock时按小键盘上的数字键并不能输入数字

    小键盘问题 在Xshell 6上用vi的时候,开NumLock时按小键盘上的数字键并不能输入数字,而是出现一个字母然后换行(实际上是命令模式上对应上下左右的键).解决方法 选项Terminal-> ...

  9. 使用JFileChooser实现在指定文件夹下批量添加根据“数字型样式”或“非数字型样式”命令的文件夹

    2018-11-05 20:57:00开始写 Folder.java类 import javax.swing.JFrame; import javax.swing.JPanel; import jav ...

随机推荐

  1. BZOJ - 2744 朋友圈 (二分图上的最大团)

    [题目大意] 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着.一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大数目.两 ...

  2. 动态规划:ZOJ1074-最大和子矩阵 DP(最长子序列的升级版)

    To the Max Time Limit:1 Second     Memory Limit:32768 KB Problem Given a two-dimensional array of po ...

  3. Android 获取当前应用的版本号+版本号比较

       前言:因为项目更新的时候需要一些版本号的信息,后台返回两个string,一个是最低兼容版,一个是最新版.所以拿到数据后要比较一下,所以封装了一个Common包来处理. Step 1 废话不多说, ...

  4. P2065 贪心的果农

    P2065 贪心的果农 题目描述 果农的花园里种着N棵果树.收获的季节终于来到了,果农决定,在接下来的M天时间里完成自己的收获工作.他的收获方式极其暴力——他将会将某棵果树砍倒来获取上面的果实.然而如 ...

  5. IT帮2019年2月线下活动【定义工作,解读自我】之站桩练习

    2019年2月IT帮线下活动[定义工作,解读自我] 昨天的活动收获很大,全面的总结周老师会另写一篇来帮助大家回顾.我想说一下其中最打动我的一句话:“只有你能决定你有多优秀!” “工作中把自己当成企业家 ...

  6. mongoTemplate学习笔记

    mongoTemplate的andExpression表达式 Aggregation<Post> agg = Aggregation.newAggregation( Record.clas ...

  7. Python框架之Django学习笔记(八)

    模板继承 到目前为止,我们的模板范例都只是些零星的 HTML 片段,但在实际应用中,你将用 Django 模板系统来创建整个 HTML 页面. 这就带来一个常见的 Web 开发问题: 在整个网站中,如 ...

  8. 【4Sum】cpp

    题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = ...

  9. linux环境搭建系列之tomcat安装步骤

    前提: Linux centOS 64位 JDK 1.7 安装包从官网上下载 安装Tomcat之前要先安装JDK. 我的JDK是1.7版本的,所以Tomcat版本也选了7的 1.新建目录tomcat ...

  10. python 学习分享-实战篇增删改查作业

    一大波函数来袭 作业要求: 1本次作业通过空格及逗号,将文件拆分成列表,在通过判断add.del.update.select等关键字,来判断用户执行的是哪种命令,根据不同的命令调用不同的函数去处理. ...