Leetcode 1681. 最小不兼容性
暴力求解,换个问法,找k个数字,这k个数字的异或和等于(1<<n) - 1,数字的第i位为1,代表选择第i个物品,求最小不兼容性
考虑状压dp,很玄学,这么暴力居然真的可行,以后要莽一点,状压直接上就好了。。。。。其实挺简单
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
class Solution {
public:
vector<pair<int,int> >ins;
ll dp[100000];
int minimumIncompatibility(vector<int>& nums, int k) {
int len = nums.size();
if(k == len) return 0;
int n = 1<<len;//n个状态
vector<int>a;
ins.clear();
int vis[200];
for(int i=1;i<n;i++){
dp[i] = 1e9;
int t = i;
a.clear();
int c = 0;
while(t){
if(t&1){
a.push_back(nums[c]);
}
t /= 2;
c++;
}
if(a.size() != len/k) continue;
for(int j=0;j<a.size();j++){
vis[a[j]] = 0;
}
int f = 0;
int mx = -111;
int mi = 1e9;
for(int j=0;j<a.size();j++){
if(vis[a[j]]){
f = 1;
break;
}
vis[a[j]] = 1;
mi = min(mi,a[j]);
mx = max(mx,a[j]);
}
if(f) continue;
ins.push_back(make_pair(i,mx - mi));//这个状态的价值
}
dp[0] = 0;
for(int i=0;i<n;i++){
if(dp[i] == 1e9) continue;
for(int j=0;j<ins.size();j++){
int x = ins[j].first;
int y = ins[j].second;
if((i&x) != 0) continue;//有交点
dp[i+x] = min(dp[i+x],dp[i] + y);
}
}
if(dp[n - 1] > 100000) return -1;
return dp[n-1];
}
};
寻找真正的热爱

浙公网安备 33010602011771号