LQ0084 回路计数DP

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0084 回路计数DP相关的知识,希望对你有一定的参考价值。

题目来源:蓝桥杯2021初赛 C++ A组D题

题目描述
蓝桥学院由21 栋教学楼组成,教学楼编号1 到21。
对于两栋教学楼a 和b,当a 和b 互质时,a 和b 之间有一条走廊直接相连,两个方向皆可通行,否则没有直接连接的走廊。
小蓝现在在第一栋教学楼,他想要访问每栋教学楼正好一次,最终回到第一栋教学楼(即走一条哈密尔顿回路),请问他有多少种不同的访问方案?
两个访问方案不同是指存在某个i,小蓝在两个访问方法中访问完教学楼i 后访问了不同的教学楼。

提示:建议使用计算机编程解决问题。

问题分析
用DP来解决,不解释。

AC的C++语言程序如下:

/* LQ0084 回路计数 */

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 21;
bool g[N][N];
long long dp[N][1 << N];

int main()

    memset(g, false, sizeof g);
    for (int i = 1; i <= N; i++)
        for (int j = i + 1; j <= N; j++)
            if (__gcd(i, j) == 1)
                g[i - 1][j - 1] = g[j - 1][i - 1] = 1;

    memset(dp, 0, sizeof dp);
    dp[0][1] = 1;

    int m = 1 << N;
    for (int u = 1; u < m; u++)
        for (int i = 0; i < N; i++)
            if (u & (1 << i))
                for (int j = 0; j < N; j++)
                    if (!(u & (1 << j)) && g[i][j])
                        dp[j][u | 1 << j] += dp[i][u];

    long long ans = 0;
    for (int i = 0; i < N; i++)
        ans += dp[i][m - 1];

    cout << ans << endl;        // 881012367360

    return 0;

以上是关于LQ0084 回路计数DP的主要内容,如果未能解决你的问题,请参考以下文章

第十二届蓝桥杯 ——回路计数

Hamilton回路 旅行商TSP问题 /// dp oj1964

[HNOI2007] 神奇游乐园 [插头dp]

POJ 2288 Islands And Bridges 状态压缩dp+哈密顿回路

UOJ#39. 清华集训2014简单回路 动态规划 插头DP

AcWing 91. 最短Hamilton路径(状态压缩DP+哈密顿回路)