ACdream 1726 A Math game (dfs+二分)

http://acdream.info/problem?pid=1726

官方题解:http://acdream.info/topic?tid=4246

求n个数里面能不能选一些数出来让它们的和等于k。

因为k很大,不能用背包,但是n很小,最大为40,所以拆成了2部分,之后最大为2^20次方<1050000;每次枚举前一半的和,然后用数组存储,然后得到一个总和减去后一半的差用二分查找。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5
 6 int n,h,n1,n2,a[50],b[50],c[1050000],cnt;
 7 bool flag=0;
 8
 9 bool check(int x)
10 {
11     int l=0,r=cnt-1;
12     while(l<=r)
13     {
14         int mid=(l+r)>>1;
15         if(c[mid]==x) return 1;
16         else if(c[mid]>x) r=mid-1;
17         else l=mid+1;
18     }
19     return 0;
20 }
21 void dfs(int sum,int deep,int m,int on)
22 {
23     if(flag) return;  //剪枝
24     if(deep==m)  //到最后一个数
25     {
26         if(on) c[cnt++]=sum;  //第一次记录 和
27         else flag=check(h-sum); //第二次查找
28         return;
29     }
30     for(int i=0;i<2;i++)
31     {
32         sum+=b[deep]*i;   //累加和
33         if(sum>h) return;  //剪枝
34         dfs(sum,deep+1,m,on);
35     }
36 }
37 int main()
38 {
39     //freopen("a.txt","r",stdin);
40     while(~scanf("%d%d",&n,&h))
41     {
42         cnt=0;
43         flag=0;
44         for(int i=0;i<n;i++)
45             scanf("%d",&a[i]);
46         n1=n>>1;n2=n-n1;   //分成两半
47         for(int i=n1;i<n;i++)
48             b[i-n1]=a[i]; //后一半数用b存储
49         dfs(0,0,n2,1); //枚举所有可能的和
50         sort(c,c+cnt);  //对得到的数组进行排序 便于二分查找
51         for(int i=0;i<n1;i++)
52             b[i]=a[i];  //得到前一半的和
53         dfs(0,0,n1,0);  //枚举所有的和
54         if(flag) puts("Yes");
55         else puts("No");
56     }
57     return 0;
58 }
时间: 2024-10-07 21:00:40

ACdream 1726 A Math game (dfs+二分)的相关文章

acdream 1726 A Math game (部分和问题 DFS剪枝)

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 numberH, and you can choose some numbers from a set {a[1

ACDREAM 1726 A Math game(折半枚举+hash)

题目链接: http://acdream.info/problem?pid=1726 题意: 给定n 个数,和一个数看,判断k能否由其中的任意个数的和组成. 分析: 因为n最大为40,暴力枚举所有的情况 复杂度为 2^40 肯定TLE ,然后就想到了折半枚举 分成两半,先处理前n/2个数的组合的情况 ,把所得结果哈希一下,然后再枚举后一半 的所有情况,然后在哈希表里查找.时间复杂度为 O(2^(N/2)); 代码如下: #include <stdio.h> #include <iostr

ACdream 1726 A Math game

深搜.不过有一个强大的剪枝.就是假设之后的全部用上都不能达到H,则return. if (A[n]-A[x-1]+summ< H) return; //A[n]表示前nx项和 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 50; long long a[maxn], A[maxn]; int flag, n; long lon

ACDream 1726 A Math game (折半查找)

A Math game Time Limit: 2000/1000MS (Java/Others) Memory Limit: 256000/128000KB (Java/Others) Submit Statistic Next Problem Problem Description Recently, Losanto find an interesting Math game. The rule is simple: Tell you a number H, and you can choo

石油采集(求联通区域) 2018多校寒假集训 (dfs+二分匹配)

题目: 链接:https://www.nowcoder.com/acm/contest/76/A来源:牛客网 随着海上运输石油泄漏的问题,一个新的有利可图的行业正在诞生,那就是撇油行业.如今,在墨西哥湾漂浮的大量石油,吸引了许多商人的目光.这些商人们有一种特殊的飞机,可以一瓢略过整个海面20米乘10米这么大的长方形.(上下相邻或者左右相邻的格子,不能斜着来)当然,这要求一瓢撇过去的全部是油,如果一瓢里面有油有水的话,那就毫无意义了,资源完全无法利用.现在,商人想要知道,在这片区域中,他可以最多得

hihoCoder 1238 : Total Highway Distance(dfs + 二分)

题目连接 题意:给出n个城市,n-1条道路,求出两两路径的和. 思路:题意等价于求每天道路的使用次数,如下图所示 红色路径的使用度为以节点2为根节点的子树的节点数x * (n-x),此处为2 * 2 = 4.先按u<v的规则保存好道路,然后dfs一遍处理处每天道路的使用度,dfs过程中需要知道当前的边是哪条道路,此过程用二分查找,这中双变量的二分之前也没怎么写过. code: #include <iostream> #include <cstring> #include &l

hdu 5188 dfs+二分

get了很多新技能 当时想到了用dfs,但是排序用的是限制时间排序,一直没搞出来. 正解: 二分用时,dfs判断,为了顺利进行做题,需要按照做题开始时间排序 还可以用dp 题意: 作为史上最强的刷子之一,zhx常常参与各种比赛. 有一天,zhx去虐一场比赛.他觉得题太简单了. 这场比赛有n道题.他一眼就已经计算出他做第i道题要花ti的时间,做完后可以得到vi分. 因为他太强了,所以他被管理员盯上了.如果他在第li个单位时间前做完了第i道题,那么管理员就会认为他在作弊,然后把他的号封了. zhx不

10324 Global Warming dfs + 二分

时间限制:1000MS  内存限制:65535K提交次数:0 通过次数:0 题型: 编程题   语言: G++;GCC Description Global warming is a big problem, isn't it? It is reported that the ice of Antarctica is melting. It results that oceans are glowing and more and more places are flooded. Now the

POJ 2942 - Knights of the Round Table(双连通图 Tarjan + 二分判定)

POJ 2942 - Knights of the Round Table(双连通图 Tarjan + 二分判定) ACM 题目地址: POJ 2942 - Knights of the Round Table 题意: 有N个骑士,给出某些骑士之间的仇恨关系,骑士们开会时会围坐在一个圆桌旁.一次会议能够顺利举行,要满足两个条件: 任意相互憎恨的两个骑士不能相邻 开会人数为大于2的奇数 若某个骑士任何会议都不能参加,那么就必须将他踢出,给出骑士之间的仇恨关系,问最少需要踢出多少个骑士? 分析: 把