跟acwing那道状态压缩题差不多。这道题让自己确实明白了f[1][0]的含义。以后做类似题,要注意下标表示,否则很容易出错。
#include<iostream>
using namespace std;
const int N = 21, M = 1 << N;
long long f[M][N];
bool st[N][N];
long long res;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int main()
{
for (int i = 1; i <= 21; i++)
{
for (int j = 1; j <= 21; j++)
{
if (gcd(i, j) == 1)
{
st[i-1][j-1] = 1;
}
}
}
f[1][0] = 1; //表示终点为0,状态为1方案数为1
for (int i = 1; i < M; i++)
{
for (int j = 0; j < 21; j++)
{
if ((i >> j) & 1)
{
for (int k = 0; k < 21; k++)
{
if (i - (1 << j) >> k & 1 && st[k ][j ])
{
f[i][j] += f[i - (1 << j)][k];
}
}
}
}
}
for (int i = 0; i <21; i++)
{
res += f[(1 << N) - 1][i]; //表示经过了所有点最后终点为i的方案总和
}
cout << res << endl;
return 0;
}