题目:
题意:
给你 n n n个砝码,求在总重量不超过 c c c的情况下,能组合出的最大重量是多少
分析:
我们可以采用
d
f
s
dfs
dfs来模拟选择某个砝码
但我们看到
n
<
=
40
n<=40
n<=40,而
2
40
2^{40}
240会直接
T
T
T成狗,所以我们可以采用折半
d
f
s
dfs
dfs
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<list>
#include<ctime>
#include<iomanip>
#include<string>
#include<bitset>
#include<deque>
#include<set>
#define LL long long
using namespace std;
inline LL read(){
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
set<int> s;
LL n,c,mins,maxs,w[50];
void dfs1(LL i,LL z)
{
if(z>c) return;
if(i>n/2)
{
mins=min(mins,z);
s.insert(z);
return;
}
dfs1(i+1,z+w[i]);
dfs1(i+1,z);
return;
}
void dfs2(LL i,LL z)
{
if(z+mins>c) return;
if(i>n)
{
LL k=*--s.upper_bound(c-z);
maxs=max(maxs,z+k);
return;
}
dfs2(i+1,z+w[i]);
dfs2(i+1,z);
return;
}
int main()
{
n=read();c=read();
for(LL i=1;i<=n;i++) w[i]=read();
dfs1(1,0);
dfs2(n/2+1,0);
cout<<maxs;
return 0;
}