题目描述

有n个物品,m块钱,给定每个物品的价格,求买物品的方案数。

输入

第一行两个数n,m代表物品数量及钱数
第二行n个数,代表每个物品的价格
n<=40,m<=10^18

输出

一行一个数表示购买的方案数
(想怎么买就怎么买,当然不买也算一种)

样例输入

5 1000
100 1500 500 500 1000

样例输出

8


题解

裸的折半搜索meet-in-the-middle

由于直接爆搜肯定会TLE,考虑把整个序列分成左右两部分,对于每部分求出它所有可以消耗钱数的方案。然后考虑左右组合怎么能够使总钱数不超过m。

考虑枚举右边序列的某钱数,那么左边的钱数要求就是不超过m-右边钱数。所以可以对左边序列排序,然后再二分查找即可知道不超过m-右边钱数的数的个数。把这个个数累加到答案中即可。

时间复杂度 $O(2^{\frac n2}*\log 2^{\frac n2}=2^{\frac n2}*n)$。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll a[1 << 21] , b[1 << 21] , w[50] , m;
int ta , tb;
void dfs(int x , int n , ll now , ll *a , int &ta)
{
if(now > m) return;
if(x > n)
{
a[++ta] = now;
return;
}
dfs(x + 1 , n , now , a , ta) , dfs(x + 1 , n , now + w[x] , a , ta);
}
int main()
{
int n , i;
ll ans = 0;
scanf("%d%lld" , &n , &m);
for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &w[i]);
dfs(1 , n >> 1 , 0 , a , ta);
dfs((n >> 1) + 1 , n , 0 , b , tb);
sort(a + 1 , a + ta + 1);
for(i = 1 ; i <= tb ; i ++ )
{
if(m - b[i] >= a[ta]) ans += ta;
else ans += upper_bound(a + 1 , a + ta + 1 , m - b[i]) - a - 1;
}
printf("%lld\n" , ans);
return 0;
}

【bzoj4800】[Ceoi2015]Ice Hockey World Championship 折半搜索的更多相关文章

  1. 4800: [Ceoi2015]Ice Hockey World Championship(折半搜索)

    4800: [Ceoi2015]Ice Hockey World Championship Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 622  S ...

  2. bzoj4800 [Ceoi2015]Ice Hockey World Championship

    Description 有n个物品,m块钱,给定每个物品的价格,求买物品的方案数. Input 第一行两个数n,m代表物品数量及钱数 第二行n个数,代表每个物品的价格 n<=40,m<=1 ...

  3. 【BZOJ4800】[Ceoi2015]Ice Hockey World Championship Meet in the Middle

    [BZOJ4800][Ceoi2015]Ice Hockey World Championship Description 有n个物品,m块钱,给定每个物品的价格,求买物品的方案数. Input 第一 ...

  4. 【BZOJ4800】[Ceoi2015]Ice Hockey World Championship (meet in the middle)

    [BZOJ4800][Ceoi2015]Ice Hockey World Championship (meet in the middle) 题面 BZOJ 洛谷 题解 裸题吧,顺手写一下... #i ...

  5. 【bzoj4800】: [Ceoi2015]Ice Hockey World Championship dfs

    [bzoj4800]: [Ceoi2015]Ice Hockey World Championship N<=40所以如果直接dfs背包会TLE 考虑Meet-in-the-middle 如果把 ...

  6. BZOJ_4800_[Ceoi2015]Ice Hockey World Championship_双指针

    BZOJ_4800_[Ceoi2015]Ice Hockey World Championship_双指针 Description 有n个物品,m块钱,给定每个物品的价格,求买物品的方案数. Inpu ...

  7. [luogu4799 CEOI2015 Day2] 世界冰球锦标赛(折半搜索)

    传送门 Solution 折半搜索裸题,注意\(long long\) Code #include <cmath> #include <cstdio> #include < ...

  8. 【BZOJ4800】[CEOI2015 Day2]世界冰球锦标赛 (折半搜索)

    [CEOI2015 Day2]世界冰球锦标赛 题目描述 译自 CEOI2015 Day2 T1「Ice Hockey World Championship」 今年的世界冰球锦标赛在捷克举行.\(Bob ...

  9. 折半搜索【p4799】[CEOI2015 Day2]世界冰球锦标赛

    Description 今年的世界冰球锦标赛在捷克举行.Bobek 已经抵达布拉格,他不是任何团队的粉丝,也没有时间观念.他只是单纯的想去看几场比赛.如果他有足够的钱,他会去看所有的比赛.不幸的是,他 ...

随机推荐

  1. BZOJ 1396:识别子串 SA+树状数组+单调队列

    1396: 识别子串 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 381  Solved: 243[Submit][Status][Discuss] ...

  2. UVA 110020 Efficient Solutions (STL)

    把一个人看出一个二维的点,优势的点就是就原点为左下角,这个点为右上角的矩形,包含除了右上角以外边界,其他任意地方不存在点. 那么所有有优势的点将会形成一条下凹的曲线. 因为可能有重点,用multise ...

  3. BFS 简单思想以及代码

    BFS(广搜思想) 广度优先搜索 广度优先搜索是图论的搜索算法之一,以下便进行简单叙述 对于每一个顶点来说,都存在着三种颜色 白色,灰色,黑色 而对于每个顶点,都有三种数据类型 颜色类型,前驱或者父节 ...

  4. java基础—基础语法2

    一.语句

  5. iOS调用WebService接口

    首先有几点说在前面 一般,在请求URL的后面带有WSDL字样的需要调用WebService URL样式例子:http://ip:port/navigable/webservice/loginSeric ...

  6. TypeError: Cannot read property 'tap' of undefined

    E:\vue-project\vue-element-admin-master>npm run build:prod vue-element-admin@3.8.1 build:prod E:\ ...

  7. 一些恶搞人的c++程序

    top1: 不停打开的cmd(磁盘操作系统) 代码如下: #include<windows.h> using namespace std; int main() { system(&quo ...

  8. hash 哈希查找复杂度为什么这么低?

    hash 哈希查找复杂度为什么这么低? (2017-06-23 21:20:36) 转载▼   分类: c from: 作者:jillzhang 出处:http://jillzhang.cnblogs ...

  9. pandas删除及其映射修改操作。

    1.使用drop_duplicates()函数删除重复的行 df.drop_duplicates() 2.映射 映射的含义,创建一个映射关系,把values元素和一个特定的标签或字符串绑定 map = ...

  10. 【Python学习之七】面向对象高级编程——__slots__的使用

    1.Python中的属性和方法的绑定 正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法. (1)首先,定义一个class:  class Stu ...