题目大意:
由1~21幢教学楼,两个号码互质的教学楼之间有一条双向路。
问:从1号教学楼出发,有几种走法可以走遍所有楼,并最后回到1号楼。
状压DP:
dp[i][j]:表示i状态下,经过点j的道路数目。
所以dp[(1<<22)-2][i],求和,位最终答案。
#include<bits/stdc++.h>
typedef long long ll;
const ll mmax=1<<22;
using namespace std;
ll dp[mmax+10][55];
ll mp[55][55];
int main(){
for(int i=1;i<=21;i++){
for(int j=i+1;j<=21;j++){
if(__gcd(i,j)==1){
mp[i][j]=mp[j][i]=1;
}
}
}
dp[2][1]=1;
for(int i=2;i<=mmax-2;i++){
for(int j=1;j<=21;j++){//经过点j
if(i>>j&1){
for(int k=1;k<=21;k++){
if(i-(1<<j)>>k&1&&mp[k][j]){
dp[i][j]+=dp[i-(1<<j)][k];
}
}
}
}
}
ll ans=0;
for(int i=2;i<=21;i++){
ans+=dp[mmax-2][i];
}
cout<<ans;
return 0;
}
答案:
881012367360