贪心-试填法
链接:https://ac.nowcoder.com/acm/contest/118247/D
来源:牛客网
题目描述
小苯在研究一种特殊的数字配对问题。给定 2×n 个正整数 a1,a2,...,a2n,需要将它们恰好平分成 2 组,每组的"配对值"定义为每组 n 个数的按位与(AND)。定义两个组的"总和谐度"为两组"配对值"的最大值。现在小苯想知道,在所有可能的分组方式中,能够获得的最大总和谐度是多少?
#include<bits/stdc++.h>
#define int long long
using namespace std;
int32_t main() {ios::sync_with_stdio(false);cin.tie(nullptr);int T;cin>>T;while(T--){int n;cin >> n;vector<int> a(2 * n + 1);for (int i = 1; i <= 2 * n; i++) cin >> a[i];int ans = 0;vector<int>vis(2 * n + 1, 1);for (int bit = 40; bit >= 0; bit--) {vector<int>cnt;vector<int>nvis(2 * n + 1, 0);for (int i = 1; i <= 2 * n; i++) {if(!vis[i]) continue;if ((a[i]>>bit)&1){cnt.emplace_back(i);}}if (cnt.size() >= n){ans|=1ll<<bit;for(auto &i:cnt){nvis[i]=1;}vis=nvis;}}cout << ans << endl;}return 0;
}
试填法可以理解为贪心在数位上的具体应用,我们如果想要一个整体最大的数,那么我们没有必要让这个数每一位是最大的,我们只需要让这个数的最高位最大就可以了,如果两个数的最高位相同,那么我们就需要找次高位最大的,以此类推。
这道题具体的实现方法是每次遍历每个(被标记为 1 的)数的最高位(第bit位),如果有满足条件的一组数(cnt.size() >= n)那么把这一组数标记为 1 ,并把最高位加到答案中,这样以来我们就保证总和最大。

