LeetCode 5756. 两个数组最小的异或值之和
原题链接
困难
作者:
ITNXD
,
2021-05-30 14:26:53
,
所有人可见
,
阅读 436
详细请查看注释内容
参考代码:
class Solution {
/*
暴力:枚举b数组全排列进行异或!
思路:我们可以从前往后摆所有元素,由于后面要摆的元素和前面已摆的元素顺序无关,只与是否使用过有关!
因此:我们可以使用二进制状态来表示这个状态!
状压DP:
状态表示:f[i]表示状态为i的摆法的集合!属性:异或值和最小!
状态计算:按照最后一个摆的元素划分!
f[i] = min(f[i], f[i - (1 << j)] + (b[j] ^ a[s - 1]));
解释:若最后一个摆放元素下标为j,则之前状态为i - (1 << j)
s为已经摆放元素的个数!(也就是二进制状态中1的个数)
此时异或的两个数为 b[j] 和 a[s - 1](下标从0开始,要-1)
初始化:f[0] = 0,其他为INT_MAX
最终答案:f[(1 << n) - 1](即n个数全摆放完毕的最小异或值)
*/
public:
int minimumXORSum(vector<int>& a, vector<int>& b) {
int n = a.size();
vector<int> f(1 << n, INT_MAX);
f[0] = 0;
for(int i = 1; i < 1 << n; i ++){
// 统计当前状态用了几个数
int s = 0;
for(int j = 0; j < n; j ++)
if(i >> j & 1) s ++;
for(int j = 0; j < n; j ++)
if(i >> j & 1) f[i] = min(f[i], f[i - (1 << j)] + (b[j] ^ a[s - 1]));
}
return f[(1 << n) - 1];
}
};