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;
}
posted @ 2020-11-10 16:11  Tartarus_li  阅读(50)  评论(0编辑  收藏  举报