[折半搜索]三教

题目描述  
三教是第三教学楼的简称,也是由虚幻工作室开发的一款恐怖推理游戏,将在 2020 年一月在 Steam 上
推出第一个 Demo。
Kanade 正控制着人物玩着满是 bug 的偷跑版。在游戏中,一共有 n  个补给点,如果人物到达补给点
,将会获得体力 ai ,但是如果在这个补给点用一些操作触发 bug,将会获得体力 2^f(ai) ,其中 f(x) 表
示  x 的二进制表示中 1的个数,最牛的 bug 莫过于到达补给点之后你可以选择不要提供的体力,也就
是操作之后玩家将不会获得任何体力,Kanade 也掌握了这个 bug 的触发方法。
因为之后要对战 boss,因此要收集足够的体力,但是如果打过 boss 并且剩了体力就无法触发后续剧
情,所以要求收集体力恰好为 X。Kanade 可以随心所欲地触发或不触发任意补给点的任何 bug,请问
她有多少种方式能够在全部走完这 n 个补给点后收集到 X体力。

输入
从  building.in  中读入以下内容:
第一行两个非负整数n,X  ,表示补给点个数和需要收集的体力数;
第二行 n 个非负整数  ai,第  i 个整数表示在不触发 bug 的情况下补给点 i  提供的体力。
输出
输出到  building.out。
输出一行一个整数,表示收集到 X 体力的方法数。

对于 60% 的数据,1<=n<=10 ;
对于 100%  的数据,1<=n<=25,1<=X,ai<=1e13 。

Solution

折半搜索

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<map>
 4 using namespace std;
 5 const int N=30;
 6 int n; long long X,ans,a[N],f[N];
 7 inline int cal(long long x)
 8   {int cnt=0;
 9    while(x) x=(x&(x-1)),cnt++;
10    return cnt;
11   }
12 map<long long,long long> s;
13  void dfs(int i,long long x)
14   {if(x>X)   return;
15
16    if(i>n/2) {s[x]++; return ;}
17    dfs(i+1,x); dfs(i+1,x+a[i]); dfs(i+1,x+f[i]);
18   }
19 void hehe(int i,long long x)
20   {if(x>X)   return;
21    if(i>n) {ans=ans+s[X-x];return ;}
22    hehe(i+1,x); hehe(i+1,x+a[i]); hehe(i+1,x+f[i]);
23   }
24 int main()
25  {
26    scanf("%d%lld",&n,&X);
27   for(int i=1;i<=n;i++) {scanf("%lld",&a[i]);  f[i]=(1ll<<cal(a[i])); }
28   dfs(1,0); hehe(n/2+1,0);
29   printf("%lld",ans);
30  return 0;
31  }

原文地址:https://www.cnblogs.com/YuXiaoze/p/11839524.html

时间: 2024-11-06 11:54:55

[折半搜索]三教的相关文章

E. Anya and Cubes (CF #297 (Div. 2) 折半搜索)

E. Anya and Cubes time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Anya loves to fold and stick. Today she decided to do just that. Anya has n cubes lying in a line and numbered from 1 to n

算法复习——哈希表+折半搜索(poj2549)

搬讲义~搬讲义~ 折半搜索感觉每次都是打暴力时用的啊2333,主要是用于降次··当复杂度为指数级别时用折半可以减少大量复杂度··其实专门考折半的例题并不多···一般都是中途的一个小优化··· 然后折半搜索常常与哈希表一起使用··尤其是遇到方程类的问题时··· 哈希表就不说了吧···毕竟比较简单···不懂得看下面题的代码就行了,一道折半与哈希表联合运用的经典方程模型题··· Description Given S, a set of integers, find the largest d suc

FZU 2178 礼物分配 (折半搜索+二分)

题目地址:FZU 2178 由于n最大是30,一次全搜的话妥妥的超时,那么可以采用折半搜索.分成相同的两份,对左边的一堆进行预处理,然后再处理右堆,每一次都对左堆进行二分,找最接近的.由于两个人取的不能相差多于1个,所以要对每个个数分开存储.并排序,排序是为了后边的二分. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <

位运算符 优先级 折半搜索

看编程珠玑,深知二分搜索的用处之大,自己写了一遍,竟然出了死循环.代码如下: 1 int bsearch(int *data, int val,int left, int right) 2 { 3 if(left <= right) 4 { 5 int mid = left + (right-left)>>1; 6 if(data[mid]==val) 7 return mid; 8 else if(data[mid]<val) 9 return bsearch(data,val,

【bzoj4800】[Ceoi2015]Ice Hockey World Championship 折半搜索

题目描述 有n个物品,m块钱,给定每个物品的价格,求买物品的方案数. 输入 第一行两个数n,m代表物品数量及钱数 第二行n个数,代表每个物品的价格 n<=40,m<=10^18 输出 一行一个数表示购买的方案数 (想怎么买就怎么买,当然不买也算一种) 样例输入 5 1000 100 1500 500 500 1000 样例输出 8 题解 裸的折半搜索meet-in-the-middle 由于直接爆搜肯定会TLE,考虑把整个序列分成左右两部分,对于每部分求出它所有可以消耗钱数的方案.然后考虑左右

折半搜索+状态压缩【P3067】 [USACO12OPEN]平衡的奶牛群Balanced Cow S…

Description 给n个数,从中任意选出一些数,使这些数能分成和相等的两组. 求有多少种选数的方案. Input 第\(1\)行:一个整数\(N\) 第\(2\)到\(N+1\)行,包含一个整数\(m_i\) Output 一行:平衡的集合的个数. 看到题的一瞬间数据范围? \(N \leq 20?\)状压! 明显直接做过不去,选择折半搜索. 折半搜索的话会有三种情况 一.选择当前位置 二.选择当前位置,给第一组. 三.选择当前位置,给第二组. 然后直接跑折半搜索+状压即可. 存储类似链式

codeforces 880E. Maximum Subsequence(折半搜索+双指针)

E. Maximum Subsequence time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output You are given an array a consisting of n integers, and additionally an integer m. You have to choose some sequence of

CF1221G Graph And Numbers(折半搜索+图论)

答案=总数-无0-无1-无2+无01+无02+无12-无012 直接详细讲无0和无2 无0为 01和11,无2为01和00,显然二者方案数相同,以下考虑无0 考虑折半搜索,后半段搜索,二进制点权0的位置,保证后半段构成的无0边的基础上 可以得出一个S集合,表示集合内的点随意选择,不在集合内的点只能为1 再搜索前半段,同后半段搜索,得出一个集合T里面的点权为0,则T的贡献为满足\(T\subseteq S\)的S的个数,这个子集和一下即可 原文地址:https://www.cnblogs.com/

折半搜索

折半搜索 (meet in the middle) /* reference: translation: solution: trigger: note: * date: 2019.09.04 */ #include<bits/stdc++.h> using namespace std; #define int long long #define rep(i,a,b) for(int i=a;i<=b;++i) #define dwn(i,a,b) for(int i=a;i>=b