zoukankan      html  css  js  c++  java
  • 折半搜索【p4799】[CEOI2015 Day2]世界冰球锦标赛

    Description

    今年的世界冰球锦标赛在捷克举行。Bobek 已经抵达布拉格,他不是任何团队的粉丝,也没有时间观念。他只是单纯的想去看几场比赛。如果他有足够的钱,他会去看所有的比赛。不幸的是,他的财产十分有限,他决定把所有财产都用来买门票。

    给出 Bobek 的预算和每场比赛的票价,试求:如果总票价不超过预算,他有多少种观赛方案。如果存在以其中一种方案观看某场比赛而另一种方案不观看,则认为这两种方案不同。

    Input

    第一行,两个正整数 (N)(M)((1 leq N leq 40,1 leq M leq 10^{18})),表示比赛的个数和 Bobek 那家徒四壁的财产。

    第二行,(N) 个以空格分隔的正整数,均不超过 (10^{16}),代表每场比赛门票的价格。

    Output

    输出一行,表示方案的个数。由于 (N) 十分大,注意:答案 (le 2^{40})

    显然这个题直接dfs是过不去的(O(2^n))

    但是我们可以一半一半的搜,即折半搜索,复杂度可以降到(O(2^{frac{n}{2}}))

    所以我们取一个(mid),分别搜前半段和后半段。

    然后合并答案的时候就需要令某一个数组变得有序,在其中找到最靠右的合法位置,直接累加即可。

    这里用到了(upper)_(bound)

    代码

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define R register
    #define lo long long
    
    using namespace std;
    
    const int gz=1e6+6e5;
    
    inline void in(R lo &x)
    {
    	R int f=1;x=0;char s=getchar();
    	while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    	while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    	x*=f;
    }
    
    lo a[gz],b[gz],mon[42],ans,m;
    
    int sum,cnt,n,mid;
    
    void dfs(R int dep,R lo now)
    {
    	if(now>m)return;
    	if(dep>mid)
    	{
    		a[++cnt]=now;
    		return;
    	}
    	dfs(dep+1,now+mon[dep]);
    	dfs(dep+1,now);
    }
    
    void dfss(R int dep,R lo now)
    {
    	if(now>m)return;
    	if(dep>n)
    	{
    		b[++sum]=now;
    		return;
    	}
    	dfss(dep+1,now+mon[dep]);
    	dfss(dep+1,now);
    }
    
    int main()
    {
    	scanf("%d%lld",&n,&m);
    	for(R int i=1;i<=n;i++)in(mon[i]);
    	mid=(n+1)/2;
    	dfs(1,0);dfss(mid+1,0);
    	sort(b+1,b+sum+1);
    	for(R int i=1;i<=cnt;i++)
    		ans+=upper_bound(b+1,b+sum+1,m-a[i])-b-1;
    	printf("%lld",ans);
    }
    
  • 相关阅读:
    RF学习笔记
    解决pycharm下git命令使用时中文显示乱码
    Django2.2 学习笔记1-概念篇
    cookie、session、token的理解
    win10下安装与使用mysql
    Redis学习笔记
    MongoDB与pymongo学习笔记
    记:打开Charles后,win10 chrome访问https的网站提示“您的链接不是私密链接”的解决过程
    charles抓包教程
    jmeter遍历时间戳
  • 原文地址:https://www.cnblogs.com/-guz/p/10013242.html
Copyright © 2011-2022 走看看