2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP

题目描述

蓝桥学院由21栋教学楼组成,教学楼编号1到21。对于两栋教学楼a和b,当a和b互质时,a和b之间有一条走廊直接相连,两个方向皆可通行,否则没有直接连接的走廊。

小蓝现在在第一栋教学楼,他想要访问每栋教学楼正好一次,最终回到第一栋教学楼(即走一条哈密尔顿回路),请问他有多少种不同的访问方案?两个访问方案不同是指存在某个i,小蓝在两个访问方法中访问完教学楼i后访问了不同的教学楼。

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

解题思路

哈密尔顿回路是经典的NP难问题,暴力搜索效率太低,到后面时间非常长。采用状态压缩DP,可以在2秒左右完成遍历求解,时间可以接受。

dp数组解释:dp[i][j]表示当前正在i结点,走过的路径为j时的方案数。

状态转移方程:dp[j][S|(1<<j)]=dp[j][S|(1<<j)]+dp[i][S]

解释:从i结点转移到j结点,当前到达j结点,S为到达i结点时所走过的结点序列(二进制表示,如10101表示走过了1、 3、 5三结点,没有走过2、 4两个结点),则dp[j][S|(1<<j)]表示到达j结点时的访问方案数量。S|(1<<j)含义:S序列中第j个二进制位一定为0,因为还没有访问第j个结点,到达j节点之后,要将第j个二进制位置一。'|'和'<<'分别为按位或和左移操作。dp[i][S]为到达i结点时的不同访问方案数。即下一个结点的访问方案数为其所有前驱结点访问方案数的和。

注意:本题结果数字很大,dp数组和结果都要使用long long类型

答案

881012367360

代码实现

(关键代码已加注释)

#include<bits/stdc++.h>
using namespace std; typedef long long ll; const int n=21;
bool G[n][n];//边采用邻接矩阵存储
ll dp[n][1<<n]; void generateEdge(){//生成边
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]=1;
G[j-1][i-1]=1;
}
}
}
} int main(){
memset(dp,0,sizeof dp);
memset(G,0,sizeof G);
dp[0][1]=1;//初始在0结点时,路径为000...1,方案数为1
generateEdge();
int m=1<<n;
for(int S=1;S<m;S++){//遍历访问序列
for(int i=0;i<n;i++) if(S&(1<<i))//遍历当前访问的结点,当前访问的结点其访问的序列中该二进制位必须为1
for(int j=0;j<n;j++){//遍历下一个访问结点
if(!(S&(1<<j))&&G[i][j])//如果j结点没有访问且i和j之间有边则状态转移
dp[j][S|1<<j]+=dp[i][S];
}
}
ll ans=0;
for(int i=0;i<n;i++){
ans+=dp[i][m-1];//最终的访问序列为全部访问过,即访问序列为21个1,可以从不同的结点开始访问,遍历求和
}
cout<<ans;
return 0;
}

2021蓝桥杯省赛C++A组试题E 回路计数 状态压缩DP详细版的更多相关文章

  1. 2021蓝桥杯省赛B组(C/C++)E.路径【最短路DP】

    2021蓝桥杯省赛B组题目(C/C++)E.路径 最短路径, 因为变化情况比较多, 所以开始想的是深搜, 但是太慢了, 跑不出来, 后来就想着优化一下, 有的地方到另一个地方可能会考虑很多遍, 于是考 ...

  2. 第八届蓝桥杯国赛java B组第三题

    标题:树形显示 对于分类结构可以用树形来形象地表示.比如:文件系统就是典型的例子. 树中的结点具有父子关系.我们在显示的时候,把子项向右缩进(用空格,不是tab),并添加必要的连接线,以使其层次关系更 ...

  3. 第四届蓝桥杯省赛 (JavaB组)

    第二题:马虎的算式 小明是个急性子,上小学的时候经常把老师写在黑板上的题目抄错了. 有一次,老师出的题目是:36 x 495 = ? 他却给抄成了:396 x 45 = ? 但结果却很戏剧性,他的答案 ...

  4. 2016年蓝桥杯省赛C++A组 消除尾一

    消除尾一: 下面的代码把一个整数的二进制表示的最右边的连续的1全部变成0如果最后一位是0,则原数字保持不变. 如果采用代码中的测试数据,应该输出: 00000000000000000000000001 ...

  5. 蓝桥杯第十届C组试题C

    从0开始,从右到左给这些字符串的每一位字母起个名字. 比如:A(1位)A(0位) A(2位)A(1位)A(0位) AA = 27, 可以看成(26 * 1)+ A(1) 因为:字母每经过一个轮回,可就 ...

  6. 52-2018 蓝桥杯省赛 B 组模拟赛(一)java

    最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增.比如 212212 就是一个U型数字,但是 333333, 9898, 567567, 313133131 ...

  7. 带分数--第四届蓝桥杯省赛C++B/C组

    第四届蓝桥杯省赛C++B/C组----带分数 思路: 1.先枚举全排列 2.枚举位数 3.判断是否满足要求 这道题也就是n=a+b/c,求出符合要求的abc的方案数.进行优化时,可以对等式进行改写,改 ...

  8. 计蒜客蓝桥杯模拟赛 后缀字符串:STL_map+贪心

    问题描述 一天蒜头君得到 n 个字符串 si​,每个字符串的长度都不超过 10. 蒜头君在想,在这 n 个字符串中,以 si​ 为后缀的字符串有多少个呢? 输入格式 第一行输入一个整数 n. 接下来  ...

  9. 2013第四届蓝桥杯决赛Java高职高专组题目以及解法答案

    2013第四届蓝桥杯决赛Java高职高专组题目以及解法答案 不知不觉离决赛都过去一个月了,一直忙于各种事情,都忘记整理一份试题.当作回忆也好. 1. 标题:好好学习 汤姆跟爷爷来中国旅游.一天,他帮助 ...

随机推荐

  1. 利用es6解构赋值快速提取JSON数据;

    直接上代码 { let JSONData = { title:'abc', test:[ { nums:5, name:'jobs' }, { nums:11, name:'bill' } ] } l ...

  2. CommonsCollection6反序列化链学习

    CommonsCollection6 1.前置知识 1.1.HashSet HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合.继承了序列化和集合 构造函数参数为空的话创建一 ...

  3. 取地址与解引用 C指针浅析

    C语言指针入门需要掌握的两个概念就是取地址&和解引用*,下面我们按例子来理解这两个符号的使用. int main() { int a = 0; int* pa = &a;//取地址操作 ...

  4. Linux下编写和加载 .ko 文件(编写linux驱动)

    一..ko 文件介绍 .ko文件是kernel object文件(内核模块),该文件的意义就是把内核的一些功能移动到内核外边, 需要的时候插入内核,不需要时卸载. 二.优点 (1)这样可以缩小内核体积 ...

  5. Python学习报告及后续学习计划

    第一次有学习Python的想法是源于寒假在家的时候,高中同学问我是否学了Python(用于深度学习),当时就到b站收藏了黑马最新的教学视频,但是"收藏过等于我看了",后续就是过完年 ...

  6. partTwo自动出题程序第二阶段

    (1)题目避免重复: (2)可定制(数量/打印方式): 代码实现 import java.util.ArrayList;import java.util.Random;import java.util ...

  7. MySQL数据库常识之储存引擎

    我的博客 储存引擎分类 show engines; 这个命令可以查看数据库的数据引擎,可以看到InnoDB是默认的引擎. 命令除了在终端运行,也可以在查询数据库可视化工具中运行. 而,(我是5.7版本 ...

  8. MySQL备份迁移之mydumper

    简介 mydumper 是一款开源的 MySQL 逻辑备份工具,主要由 C 语言编写.与 MySQL 自带的 mysqldump 类似,但是 mydumper 更快更高效. mydumper 的一些优 ...

  9. Halo 开源项目学习(三):注册与登录

    基本介绍 首次启动 Halo 项目时需要安装博客并注册用户信息,当博客安装完成后用户就可以根据注册的信息登录到管理员界面,下面我们分析一下整个过程中代码是如何执行的. 博客安装 项目启动成功后,我们可 ...

  10. linux在图形界面一登录就自动闪退

    今天一登录linux图形界面就自动退出了,又退到了登录界面了,密码是正确的. 解决方法如下: 1. 先按 Ctrl + Alt + F1,进入 命令行模式. 2. 在命令行里,输入用户名密码正常登录. ...