折半搜索求调
查看原帖
折半搜索求调
402384
orgn楼主2022/7/13 10:22
#include <bits/stdc++.h>
using namespace std;
#define N 1<<21
int n, m[25];
int a[N], b[N];
bool c[N];
long long f1[N], len1 = 0, f2[N], len2 = 0, ans = 0;
void dfs(int x, int y, int now,long long sum) {
	if (y == 1 && x == n / 2 + 1) {
		f1[++len1] = sum;
		a[len1] = now;
		return;
	}
	if (y == 2 && x == n + 1) {
		f2[++len2] = sum;
		b[len2] = now;
		return;
	}
	dfs(x + 1, y, now,sum);
	dfs(x + 1, y, now + (1 << (x-1)),sum+m[x]);
	dfs(x + 1, y, now + (1 << (x-1)),sum-m[x]);
}
bool cmp1(long long a, long long b) {
	return a < b;
}
bool cmp2(long long a, long long b) {
	return a > b;
}
int main () {
	cin >> n;
	for (int i = 1; i <= n; i++) cin >> m[i];
	dfs(1, 1, 0,0), dfs(n / 2 + 1, 2, 0,0);
	sort(f1 + 1, f1 + 1 + len1, cmp1);
	sort(f2 + 1, f2 + 1 + len2, cmp2);
//	for(int i=1;i<=len1;i++) cout<<f1[i]<<" ";cout<<endl;
//	for(int i=1;i<=len2;i++) cout<<f2[i]<<" ";cout<<endl;
	int l = 1, r = 1;
	while (l <= len1 && r<=len2) {
		while (f1[l] + f2[r] > 0 && r <= len2) r++;
		int cnt = r;
		while (f1[l] + f2[r] == 0 && r <= len2) {
			if (c[a[l] | b[r]]==false) c[a[l] | b[r]] = true, ans++;
			r++;
		}
		if (f1[l] == f1[l + 1] && l<len1) r=cnt;
		l++;
	}
	cout << ans-1 << endl;
	return 0;
}

我这题调了2个多小时,就差把题解抄一遍了……

2022/7/13 10:22
加载中...