zoukankan      html  css  js  c++  java
  • 联赛膜你测试24 答题 题解

    前言:

    我严重怀疑这题是个卡常题。。。

    最后把sort换成stable_sort才过去,人都傻了

    解析:

    首先要看对题啊,

    上来整个双重否定句,欺负我语文烂?那我也没办法嘤嘤嘤

    大概意思就是,给你n个数,这些数显然可以组成(2^n) 个数(每个数选或不选),要你选一个数,问至少要多大才能够有不多于(1<<n)*(1-p) 个数比你的数大。
    。。。。好像还是很绕
    总之就是这样啦

    首先考虑爆搜,可以拿到30分的好成绩,因为n>20以后,(O(2^n))的复杂度就萎了。那这时怎么办呢?
    可以考虑类似于折半搜索的方法,先处理出前n/2个数能够拼出的所有数,再处理出后n/2个数能够拼出的所有数,最后再二分答案。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1500000+10;
    const double eps=1e-9;
    int b[50];
    ll a[maxn],c[maxn];
    int n,tot,cnt;
    double p;
    ll ss;
    void dfs(int now,ll w){
    	if(now>n){
    		a[++tot]=w;
    		return;
    	}
    	dfs(now+1,w);
    	dfs(now+1,w+b[now]);
    }
    bool cmp(int x,int y){
    	return x<y;
    }
    void Solve1(){
    	dfs(1,0);
    	sort(a+1,a+tot+1,cmp);
    	double x=((double)tot*p);
    	int y=(int)x;
    	if(x-y>eps) y++;
    	printf("%lld
    ",a[y]);
    }
    void dfs2(int now,ll w){
    	if(now>(n/2)){
    		a[++tot]=w;
    		return;
    	}
    	dfs2(now+1,w);
    	dfs2(now+1,w+b[now]);
    }
    void dfs3(int now,ll w){
    	if(now>n){
    		c[++cnt]=w;
    		return;
    	}
    	dfs3(now+1,w);
    	dfs3(now+1,w+b[now]);
    }
    bool check(int x){
    	int head=1;
    	ll res=0;
    	for(register int i=cnt;i;--i){
    		while(c[i]+a[head]<=x){
    			if(head>tot) break;
    			head++;
    		}
    		if(head>tot) break;
    		res+=tot-head+1;
    	}
    	return res<ss ;
    }
    void Solve2(){
    	dfs2(1,0);
    	dfs3(n/2+1,0);
    	stable_sort(a+1,a+tot+1,cmp);
    	stable_sort(c+1,c+cnt+1,cmp);
    	double s=(double)(1ll<<n)*(1.0-p);
    	ss=(ll)s;
    	if(s-ss>eps) ss++;
    	int l=1,r=a[tot]+c[cnt];
    	while(l<=r){
    		int mid=(l+r)>>1;
    		if(check(mid)) r=mid-1;
    		else l=mid+1;
    	}
    	printf("%d
    ",l);
    }
    void Solve(){
    	scanf("%d%lf",&n,&p);
    	for(register int i=1;i<=n;++i) scanf("%d",&b[i]);
    	if(n<=20){
    		Solve1();
    		return;
    	}
    	Solve2();
    }
    int main(){
    	freopen("answer.in","r",stdin);
    	freopen("answer.out","w",stdout);
    	Solve();
    	return 0;
    }
    
    
  • 相关阅读:
    bzoj 2002 [Hnoi2010]Bounce 弹飞绵羊
    【无图慎入】Link Cut Tree 总结
    cogs1889 [SDOI2008]Cave 洞穴勘测 link-cut tree
    Codeforces Round #452 (Div. 2)
    【正经向】NOIP2017烤后总结
    cogs1772 [国家集训队2010]小Z的袜子
    noip2017普及题解
    noip2017 TG 游记
    noip2017 PJ AK记
    jzoj5341 捕老鼠
  • 原文地址:https://www.cnblogs.com/wwcdcpyscc/p/13887756.html
Copyright © 2011-2022 走看看