hhhhh五轮领先7分
就很开心
之前听说过meet in the middle
但是一直没写过
所以根本没想到
其实这题算裸题了
#include<cstdio>
#include<cstring>
#include<algorithm>
int a[50];
int ans[(1<<20)+20];
int cnt;
int find(int x)
{
int ll=1,rr=cnt;
while(rr-ll>1)
{
int mid=(ll+rr)>>1;
if(ans[mid]<=x) ll=mid;
else rr=mid-1;
}
if(ans[rr]<=x) return ans[rr];
if(ans[ll]<=x) return ans[ll];
return 0;
}
int main()
{
freopen("drink.in","r",stdin);
freopen("drink.out","w",stdout);
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int mid=n/2;
int top=(1<<mid)-1;
for(int i=0;i<=top;i++)
{
int j=i,tmp=1,sum=0;
bool tag=1;
while(j&&tag)
{
if(j&1)
{
sum+=a[tmp];
if(sum>m) tag=0;
}
j=j>>1;tmp++;
}
if(tag) ans[++cnt]=sum;
}
std::sort(ans+1,ans+1+cnt);
top=(1<<(n-mid))-1;
int max=0;
for(int i=0;i<=top;i++)
{
int j=i,tmp=mid+1,sum=0;
bool tag=1;
while(j&&tag)
{
if(j&1)
{
sum+=a[tmp];
if(sum>m) tag=0;
}
j=j>>1;tmp++;
}
if(tag)
{
int x=find(m-sum)+sum;
max=max>x?max:x;
}
}
printf("%d\n",max);
fclose(stdin);
fclose(stdout);
return 0;
}