关灯问题II 状压DP \(n\)个灯,\(m\)个按钮,每个按钮都会对每个灯有不同影响,问最少多少次使灯熄完. \(n\le 10,m\le 100\) 状压DP的好题,体现了状压的基本套路与二进制操作 注意到此题\(n\)极小,一般小于\(16\)就可以做状压,并且发现每次转移时需要每盏灯的信息,于是我们直接将灯状态塞进二进制即可. 首先我们从初态开始按顺序枚举状态,然后枚举每次状态的决策,最后按题意转移到下一个状态即可. #include <cstdio> #include <al…
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int n,m; ];//a[i][j] : 第i个开关对第j个灯的效果. )];//vis[i] : 判断状态i是否被访问过 struct Node { int status;//状态 int minTimes;//来到当前状态按下开关的最小次数 Node(,):status(a),minTimes(b){} }; queue<Node >myqueue;/…
$ \color{#0066ff}{ 题目描述 }$ 俗话说种瓜得瓜,种豆得豆,MloVtry把自己砍掉一半埋进了土里,于是它得到了一颗n个点的咸鱼树. 但是问题是由于MloVtry只舍得埋下一半的自己,所以这个咸鱼树是不完整的---甚至它碎裂成了m条边. 作为一条能够致癌的咸鱼,MloVtry当然想要一颗咸鱼树来标榜自己的身份. MloVtry大概估计出了连接两个点之间的代价,它想知道,最少需要多少代价才能拼出咸鱼树? 值得注意的是,咸鱼树上的咸鱼边们对于MloVtry是很有意见的,所以每条边…
传送门 本以为是状压DP,但是有后效性. 所以写一手状压spfa #include <queue> #include <cstdio> #include <cstring> #include <iostream> #define N 11 #define M 101 int n, m; int a[M][N], dis[1 << N]; std::queue <int> q; bool vis[1 << N]; inlin…
题目链接 给n个点 n<=18. 然后给出它们两两之间是否有边相连. 问你这个图的所有子集,最少要用多少种颜色来染色, 如果两个点相连, 那么这两个点不能染同样的颜色. 先预处理出所有的点独立集, 然后直接状压枚举所有的状态. 对每种状态枚举这个状态的所有子状态进行转移即可. #include <bits/stdc++.h> using namespace std; #define ll long long #define mem(a) memset(a, 0, sizeof(a)) )…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 题意:中文题目 解法:状压DP,dp[i][j]代表前i个低点,当前高点状态为j的方案数,然后枚举转移就好了,我的代码里为什么要用滚动优化,内存?内存是足够的,不需要优化,我的dp表示是前i个低点所以转移不是从i-1转移,是从前一个低点转移,所以滚动数组能完美解决这个问题. #include <bits/stdc++.h> using namespace std; typedef long…
题目链接 Solution 这道题算是很经典的状压问题了,好题. 考虑到 \(n\) 的范围仅为 \(10\) , 那么也就是说所有状态压起来也只有 \(1024\) 种情况. 然后我们发现 \(m\) 居然小于 \(100\) . 于是可以 \(O(nm)\) 处理出每一种情况可以到达的结果. 然后形成一个有向图,然后直接跑 \(SPFA\) 就好了. Code /* Problem: P2622 Time : Day -96 */ #include<bits/stdc++.h> using…
#\(\color{red}{\mathcal{Description}}\) \(Link\) 现有\(n\)盏灯,以及\(m\)个按钮.每个按钮可以同时控制这\(n\)盏灯--按下了第i个按钮,对于所有的灯都有一个效果.按下\(i\)按钮对于第\(j\)盏灯,是下面\(3\)中效果之一:如果\(a[i][j]\)为1,那么当这盏灯开了的时候,把它关上,否则不管:如果为\(-1\)的话,如果这盏灯是关的,那么把它打开,否则也不管:如果是\(0\),无论这灯是否开,都不管. 现在这些灯都是开的,…
传送门 题意: 一个无向图,从$1$到$n$,要求必须经过$2,3,...,k+1$,给出一些限制关系,要求在经过$v \le k+1$之前必须经过$u \le k+1$ 求最短路 预处理出$1...k+1$到其他点的最短路 然后$f[i][s]$表示当前在$i$已经经过的点的集合为$s$的最短路 只考虑$1,2,...,k+1$就行了, 注意$1$也要考虑,一个点可能经过多次 然后实测dij比spfa快....我想试$pb\_ds$来着结果发现我的电脑上没有ext/pb_ds/priority…
传送门 n <= 20 很小 所以可以状态压缩 然后因为可能存在环,所以不能DP 那么就用spfa找最短路 被位运算坑了,不清楚优先级一定要加括号 ——代码 #include <queue> #include <cstdio> #include <cstring> #include <iostream> #define M 301 #define N 4000001 int n, m; int b1[M], b2[M], f1[M], f2[M], a…