P4799 [CEOI2015 Day2] 世界冰球锦标赛

原题链接

题解

折半搜索
前半部分的所有组合(二进制表示)存起来,然后遍历后半部分的组合,找到第一个加起来不大于M的

= code

#define ll long long
#include<bits/stdc++.h>
using namespace std;

inline void read(ll &x) {  
	x = 0;
	ll flag = 1;
	char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-')flag = -1;
        c = getchar();
    }
	while(c >= '0' && c <= '9') {
		x = (x << 3) + (x << 1) + (c ^ 48); 
		c = getchar();
	}
	x *= flag;
}

inline void write(ll x)
{
    if(x < 0){
    	putchar('-');
		x = -x;
	}
    if(x > 9) 
		write(x / 10);
    putchar(x % 10 + '0');
}

ll n,m,mid;
ll a[23]={0},b[23]={0};
ll vala[(1<<21)+5]={0};

int main()
{
    read(n); read(m);
    mid=n>>1;
    for(ll i=1;i<=mid;i++) read(a[i]);

    for(ll i=1;i<=n-mid;i++) read(b[i]);

    ll cnt=(1<<mid);
    for(ll i=0;i<=(1<<mid)-1;i++)
        for(ll k=1;k<=mid;k++)
            if((1<<(k-1))&i) vala[i]+=a[k];

    sort(vala,vala+cnt);

    mid=n-mid;
    ll ans=0;
    for(ll i=0;i<=(1<<mid)-1;i++)
    {
        ll sum=0;
        for(ll k=1;k<=mid;k++) if((1<<(k-1))&i) sum+=b[k];
        ans+=lower_bound(vala,vala+cnt,m-sum+1)-vala;
    }
    write(ans);
    putchar('\n');
    return 0;
}
posted @   纯粹的  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示