AcWing 171 送礼物(折半搜索/双向搜索)
https://www.acwing.com/problem/content/173/
折半搜索经典题目
按重量从大到小排序搜索
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 26;
const ll INF = (1LL) << (58LL);
int N, cnt;
ll w[50], a[1 << maxn], W, ans;
void dfs1(int d, ll G, int depth){
if(d == depth + 1){
if(G <= W){
ans = max(ans, G);
a[++cnt] = G;
}
return;
}
dfs1(d + 1, G + w[d], depth);
dfs1(d + 1, G, depth);
}
void dfs2(int d, ll G, int depth){
if(d == depth + 1){
if(G <= W){
int G1 = upper_bound(a + 1, a + 1 + cnt, W - G) - a;
--G1;
ans = max(ans, G + a[G1]);
}
return;
}
dfs2(d + 1, G + w[d], depth);
dfs2(d + 1, G, depth);
}
bool cmp (int x, int y){ return x > y; }
ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
int main(){
W = read(), N = read(); cnt = 0, ans = 0;
for(int i = 1; i <= N; ++i) w[i] = read();
sort(w + 1, w + 1 + N, cmp);
int n1 = N / 2 + 1;
dfs1(1, 0, n1);
a[++cnt] = INF;
sort(a + 1, a + 1 + cnt);
cnt = unique(a + 1, a + 1 + cnt) - a - 1;
dfs2(n1 + 1, 0, N);
cout << ans << endl;
return 0;
}