嘛,其实就是一个裸的二进制枚举 套 Meeting in Middle 思想。。。
比较水。。。吧。
好像一个月前就做过。。。
#include<bits/stdc++.h>
using namespace std;
int n;
long long w,a[105],b[105],c[105],l1,l2,weight[1<<24],ans,two[25];
long long q[1<<24],tot;
inline bool cmp(long long x,long long y){
return x>y;
}
bool cmp2(long long x,long long y){
return x<y;
}
int main(){
ios::sync_with_stdio(false);
two[0]=1;
for(int i=1;i<=24;i++)two[i] = (two[i-1]<<1);
cin>>w>>n;
for(int i=0;i<n;i++)cin>>c[i];
l1=n/2+1,l2=n-n/2-1;
sort(c,c+n,cmp);
for(int i=0;i<l1;i++)a[i]=c[i];
for(int i=l1;i<n;i++)b[i-l1]=c[i];
for(long long s = 0;s<(1<<l1);s++){
long long sum=0;
for(int j=0;j<l1;j++)
if(s&two[j]){
sum+=a[j];
if(sum>w)break;
}
if(sum>w)continue;
tot++,q[tot]=sum;
ans = max(ans,sum);
}
sort(q+1,q+1+tot);
tot = unique(q+1,q+tot+1)-(q+1);
for(long long s = 0;s<(1<<l2);s++){
long long sum=0;
for(int j=0;j<l2;j++)
if(s&two[j]){
sum+=b[j];
if(sum>w)break;
}
if(sum>w)continue;
long long nowx = q[upper_bound(q+1,q+1+tot,w-sum)-q-1]+sum;
if(nowx>w)continue;
ans = max(ans,nowx);
}
cout<<ans<<endl;
}