1、B站视频链接:B26 双向DFS 送礼物_哔哩哔哩_bilibili
#include <bits/stdc++.h>
using namespace std;
int n,m;
int g[46];//存储所有物品的质量
int w[1<<23];//存储所有能凑出来的重量
int ans,cnt;//w的个数是cnt
//搜索第u个数,和为s;
void dfs1(int u,int s){
if(u==n/2){//边界
w[cnt++]=s;
return;
}
dfs1(u+1,s);//不选g[u]
if(g[u]+s<=m)dfs1(u+1,s+g[u]);//选
}
void dfs2(int u,int s){
if(u==n){
ans=max(ans,*(upper_bound(w,w+cnt,m-s)-1)+s);
return;
}
dfs2(u+1,s);//不选g[u]
if(g[u]+s<=m)dfs2(u+1,s=g[u]);//选
}
int main(){
cin>>m>>n;
for(int i=0;i<n;i++)cin>>g[i];
sort(g,g+n);
reverse(g,g+n);//优化搜索顺序
dfs1(0,0);//搜索前一半n/2
sort(w,w+cnt);cnt=unique(w,w+cnt)-w;//去重
dfs2(n/2,0);//搜索后一半(n/2,n);
cout<<ans;
return 0;
}