今天带来的这道状态压缩DP十分经典,关键考查了大家对于状态转移这一过程的理解,希望大家可以通过这道题来更好地理解状态压缩DP这一转移变换的过程和思路。
题目描述
蓝桥学院由 21 栋教学楼组成,教学楼编号 1 到 21。对于两栋教学楼 a 和 b,当 a 和 b 互质时,a 和 b 之间有一条走廊直接相连,两个方向皆可通行,否则没有直接连接的走廊。
小蓝现在在第一栋教学楼,他想要访问每栋教学楼正好一次,最终回到第一栋教学楼(即走一条哈密尔顿回路),请问他有多少种不同的访问方案?
两个访问方案不同是指存在某个i,小蓝在两个访问方法中访问完教学楼 i 后访问了不同的教学楼。
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
int g[22][22];
int dp[1<<21][22];
ll ans;
int main()
{
for(int i=1;i<=21;i++){
for(int j=1;j<=21;j++){
if(__gcd(i,j)==1){
g[i-1][j-1]=g[j-1][i-1]=1;
}
}
}
int n=(1<<21)-1;
dp[1][0]=1;
for(int i=2;i<=n;i++){
for(int j=0;j<21;j++){
if ((i & (1 << j)) == 0)continue;
int last=i^(1<<j);
for(int k=0;k<21;k++){
if(last&(1<<k)&&g[j][k]){
dp[i][j]+=dp[last][k];
}
}
}
}
for(int i=0;i<21;i++){
if(g[i][0]){
ans+=dp[n][i];
}
}
cout<<ans;
return 0;
}
这道题的易错点在于对于初始条件dp[1][0]=1的设立,对于第一次访问教学楼时将值设置为1,题意相符合。
今天的分享就到这里,希望大家多多关注。