【TC-SRM461Div1】Fencing Garden【Meet In The Middle】【二分】

2013年国家队论文题。


《搜索问题中的meet in the middle技巧》的最后一题。


/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

typedef long long LL;

const int maxn = 45, maxm = 2000005;
const double eps = 1e-5;

int n, m, num[maxn], cntA, cntB;
LL sum, A[maxm], B[maxm], ans, area;

inline int iread() {
	int f = 1, x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return f * x;
}

inline void dfs(int x, LL len, bool left) {
	if(x > (left ? m : n)) {
		if(left) A[++cntA] = len;
		else B[++cntB] = len;
		return;
	}
	dfs(x + 1, len, left);
	dfs(x + 1, len + num[x], left);
}

inline void update(LL len, LL aim, bool flag) {
	int l = 1, r = cntB;
	while(l <= r) {
		int mid = l + r >> 1;
		if(len + B[mid] < aim) l = mid + 1;
		else r = mid - 1;
	}
	for(int i = l - 1; i <= l + 1; i++) if(i >= 1 && i <= cntB) {
		LL x = len + B[i];
		if(flag) {
			LL tmp = x * (sum - x);
			if(tmp > area || (tmp == area && ans < x)) area = tmp, ans = x;
		} else {
			LL tmp = x * (sum - (x << 1)) << 1;
			if(tmp > area || (tmp == area && ans < x)) area = tmp, ans = sum - (x << 1);
		}
	}
}

int main() {
	n = iread(); m = n >> 1;
	for(int i = 1; i <= n; i++) sum += num[i] = iread();

	dfs(1, 0, 1);
	dfs(m + 1, 0, 0);

	sort(A + 1, A + 1 + cntA); cntA = unique(A + 1, A + 1 + cntA) - (A + 1);
	sort(B + 1, B + 1 + cntB); cntB = unique(B + 1, B + 1 + cntB) - (B + 1);

	for(int i = 1; i <= cntA; i++) {
		update(A[i], sum >> 1, 1);
		update(A[i], sum >> 2, 0);
	}

	printf("%lld\n", ans);
	return 0;
}


你可能感兴趣的:(搜索,in,二分,middle,the,meet)