我已经被这个问题困扰了很长时间。 https://www.hackerearth.com/code-monk-bit-manipulation/algorithm/when-the-integers-got-upset/。简而言之:有两个长度为 N 的数组 A 和 P。还有第三个数组 Z,其值计算如下:
Z[i]=(A[i] ^ A[i-1] ^ A[i-2]) times P[i] for i ≥ 2, and 0 otherwise.(^ is exor)
我们必须重新排列 A 中的值,以使 Z 中的值之和最小化。
Eg:A[4]:2 5 4 6
P[4]:1 1 1 1
我们可以将 A 中的值重新排列为 :5 6 2 4 。Z 中的相应值将为:0 0 1 0,总和为 1。
我在 O(n!) 中解决这个问题的方法,但它超过了时间限制。有使用动态编程和位掩码的 O(n^2*2^n) 方法。
Note:N<=12.
#include <limits.h>
#include <iostream>
#include<algorithm>
using namespace std;
int func(vector<int> a,vector<int> &p)
{
int res = 0;
// for(int i=0;i<a.size();i++) cout<<a[i]<<" ";
// cout<<endl;
for(int i=2 ; i<a.size() ; i++)
res += ((a[i-2]^a[i-1]^a[i])*p[i]);
// cout<<res<<endl;
return res;
}
int main()
{
int t ; cin>>t ;
while(t--)
{
int n ; cin>> n;
vector<int> a(n) , p(n) ;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) cin>>p[i];
sort(a.begin() ,a.end());
int res = INT_MAX;
do{
res = min(res,func(a,p));
}while(next_permutation(a.begin() , a.end()));
cout << res << endl;
}
return 0;
}