如下代码的时间复杂度应该是 O(n22n) 级别的,就算有剪枝为啥还能跑到最慢 280ms,位运算这么快吗?
#include <bits/stdc++.h>
using namespace std;
const int N=21;
int n;
int p[N][N],q[N][N];
int a[N][N];
int f[N][1<<20];
int count(int x)
{
int res=0;
while(x)
{
if(x&1) res++;
x>>=1;
}
return res;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&p[i][j]);
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&q[i][j]);
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=p[i][j]*q[j][i];
for(int i=1;i<=n;i++)
{
for(int j=0;j<1<<n;j++)
{
if(count(j)!=i-1) continue;
for(int k=1;k<=n;k++)
{
if(!((j>>(k-1))&1)) f[i][j+(1<<(k-1))]=max(f[i][j+(1<<(k-1))],f[i-1][j]+a[i][k]);
}
}
}
printf("%d",f[n][(1<<n)-1]);
return 0;
}