题解
折半搜索
前半部分的所有组合(二进制表示)存起来,然后遍历后半部分的组合,找到第一个加起来不大于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;
}
标签:P4799,23,Day2,ll,CEOI2015,long,getchar
From: https://www.cnblogs.com/pure4knowledge/p/18034201