买汽水
题目链接:SSLOJ/Luogu(个人题目)

解题思路
折半搜索
code
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
int ans;
int a[50];
int b[1100000],tot;
void find(int s)
{
int l=0,r=tot;
while(l<=r)
{
int mid=(l+r)/2;
if(s+b[mid]<=m)
{
ans=max(ans,s+b[mid]);
l=mid+1;
}
else
r=mid-1;
}
}
void dfs1(int now,int s)
{
if(s>m)
return;
if(now>n/2)
{
b[++tot]=s;
return;
}
dfs1(now+1,s);
dfs1(now+1,s+a[now]);
}
void dfs2(int now,int s)
{
if(s>m)
return;
if(now>n)
{
find(s);
return;
}
dfs2(now+1,s);
dfs2(now+1,s+a[now]);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
dfs1(1,0);
sort(b+1,b+tot+1);
dfs2(n/2+1,0);
cout<<ans<<endl;
}
327

被折叠的 条评论
为什么被折叠?



