题目描述

有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. win10 KMS激活

    运行 输入以管理员权限输入CMD 如果已安装密匙先卸载,没有的话可以跳过 slmgr -upk 卸载密匙命令 输入对应版密匙以及KMS地址激活 1.键入命令:slmgr -ipk XXXXX-XXXX ...

  2. 广播监听USB插入与拔出

    package com.joy.usbbroadcastreceiver; import android.content.BroadcastReceiver; import android.conte ...

  3. BCB:WebBrowser 控件说明

      控件文件:system32\shdocvw.oca  shdocvw.dll 注册:regsvr32 shdocvw.dll WebBrowser 是 IE 内核做的 VB 控件, WebBrow ...

  4. 队列的add与offer的区别

    两个方法都表示往队列里添加元素 但是当出现异常时,add方法抛出异常 而offer则返回的是false,就是啥事也没有,也不抛异常,也没有添加成功!

  5. python之golbal/nonlocal

    一.关键字 golbal nonlocal 在局部修改全局的变量为什么会报错 count = 0 def func(): count += 1 func() # UnboundLocalError: ...

  6. 记录一次mysql中自定义获取UUID的函数

    循环方式一: DELIMITER :; drop function if exists test.fn_test:; create function test.fn_test() ) begin ) ...

  7. Python Web 架构

    1. Django(全能型)2. Tornado3. BottlePython+Bottle+Sina SAE快速构建网站http://www.cnblogs.com/Xjng/p/3511983.h ...

  8. 安装cfssl证书生成工具

    wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-am ...

  9. python入门:输出1-10以内除去7的所有数(经典)

    #!/usr/bin/env python # -*-coding:utf-8 -*- #输出1-10以内除去7的所有数(经典) """ 给kaishi赋值为1,whil ...

  10. Python基础(五)——闭包与lambda的结合

    (1)变量的域 要了解闭包需要先了解变量的域,也就是变量在哪一段“上下文”是有效的(类似局部变量和全局变量的区别),举一个很简单的例子.(例子不重要,就是涉及闭包就要时刻关注这个域) def test ...