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. Exchange日志清理

    1.清理日志--完整备份 Exchange Server 2013被部署在Windows Server 2012 及以上版本的操作系统中,使用操作系统内的"Windows Server Ba ...

  2. django开发前准备工作

    安装pip(python包管理器,类似npm) 安装virtualenv(python虚拟环境,可以形成一个版本隔绝的文件夹) virtualenv使用方法 1,virtualenv  project ...

  3. C语言---魔方阵

    魔方阵的定义:在n*n的方阵中,每一行的和=每一列的和=对角线的和.(本文中涉及的n为大于3的奇数). 例如3*3的魔方阵为: 5*5的魔方阵为: 如何写魔方阵呢? 1.数字1位于第一行的正中间2.下 ...

  4. Vue整合Quill富文本编辑器

    Quill介绍 Quill是一款开源的富文本编辑器,基于可扩展的架构设计,提供丰富的 API 进行定制.截止2021年1月,在github上面已有28.8k的star. Quill项目地址:https ...

  5. 蓝桥杯 贪吃蛇长度java实现

    小明在爷爷的私人收藏馆里找到一台老式电脑.居然没有图形界面,只能用控制台编程. 如上图,是游戏时画面截图. 其中,H表示蛇头,T表示蛇尾.#表示蛇的身体,@表示身体交叉重叠的地方. 你能说出现在的贪吃 ...

  6. 安卓记账本开发学习day8之导入外部依赖

    以要使用的柱状图分析显示为例,项目文件夹最外层的build.gradle,加入下列语句 allprojects { repositories { google() jcenter() maven { ...

  7. uniapp报错:Browserslist: caniuse-lite is outdated. Please run next command `npm update`

    uni-app的编译器是基于npm的,依赖了众多包括mpvue.webpack在内的npm库,这些库又引用了一个三方库caniuser-lite.caniuser-lite这个库的代码里有个浏览器兼容 ...

  8. 『现学现忘』Git基础 — 6、Git的操作流程

    目录 1.Git的基本操作流程 2.工作区.暂存区.版本库的区别 (1)工作区 (2)版本库 (3)暂存区 (4)通过新增文件理解三个区的关系 (5)说明 1.Git的基本操作流程 初始化一个本地版本 ...

  9. 面试突击42:synchronized和ReentrantLock有什么区别?

    在 Java 中,常用的锁有两种:synchronized(内置锁)和 ReentrantLock(可重入锁),二者的功效都是相同得,但又有很多不同点,所以我们今天就来聊聊. 区别1:用法不同 syn ...

  10. 【前端干货】别再羡慕别人的Excel啦,教你点击按钮直接打开侧边栏!

    负责技术支持的葡萄又来啦. 三日不见,我们的客户又为我们发来新的问题. 这次我们需要实现的场景是在前端表格环境中,像模板按钮那样,点击之后弹出一个侧边栏,然后通过点击不同的单元格显示不同的内容. 挤接 ...