LeetCode 1879-两个数组最小的异或值
解法
题目思路来源于Here
经典状态压缩DP。定义\(dp[i]\)来表示:当前\(i\)所表示的二进制所对应的\(nums2\)数组当前位置是否用过,二进制位置为\(1\)表示用了,否则表示没有用。枚举\(nums2\)中的的每种使用情况,然后枚举\(nums1\)中的值来更新最小的\(dp\)数组。
思考
看到题目的数据范围就在想是不是状态压缩,因为跟做过的状态压缩棋盘式问题有些不匹配,所以也没想出来怎么表示状态和转移。状态压缩的问题其实需要多想多总结,但是我老是不太敢去尝试和思考这样的题目,以后慢慢都会好好学的吧。
Coding
class Solution {
int dp[1 << 14];
public:
int lowbit(int x) {
return x & -x;
}
int count(int x) {
int res = 0;
while(x) x -= lowbit(x),++res;
return res;
}
int minimumXORSum(vector<int>& nums1, vector<int>& num2) {
int n = nums1.size();
memset(dp,-1,sizeof dp);
dp[0] = 0;
int lim = 1 << n;
for(int s = 0;s < lim;++s) {
int i = count(s);
for(int j = 0;j < n;++j) {
if((s >> j) & 1) continue;
int nxt = s | (1 << j);
if(dp[nxt] == -1 || dp[nxt] > dp[s] + (nums1[i] ^ num2[j])) {
dp[nxt] = dp[s] + (nums1[i] ^ num2[j]);
}
}
}
return dp[lim - 1];
}
};