状压dp
青烟绕指柔!
我不怕千万人阻挡,只怕自己投降。
展开
-
Codeforces - Love-Hate
题目链接:Codeforces - Love-Hate因为最后的方案要 n/2 以上,所以我们显然可以随机找,然后根据当前找到的人去枚举这个人的子集。看每个合法子集最后更新答案,对于一个子集我们需要求出他的超集数量,所以sosdp即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;原创 2021-05-31 23:32:42 · 215 阅读 · 1 评论 -
[清华集训2012]串珠子
题目链接:[清华集训2012]串珠子因为得到的是一个连通图,所以我们可以考虑用任意连边的方案数减去不连通的方案数。对于不连通的方案数,我们可以让一个子集连通,然后另一个子集随意连边。但是这样子集转移的时候是会计算重复的,所以我们可以考虑固定一个点,然后对于其他点来说就是与固定的点连通,然后不与固定的点连通。固定一个点也就是减去一个点,具体实现可以通过异或掉最低位来解决。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#includ原创 2021-03-17 09:48:47 · 213 阅读 · 0 评论 -
CCA的区间
题目链接:CCA的区间因为数字都不同,所以区间长度最多24,所以我们可以求出合法的子集区间。我们枚举一个需要的子集,然后对另一个取反后的集合求最大的子集即可,这个可以sosdp。因为可以反转区间,所以一定可以达到要求。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const in原创 2021-03-12 22:21:06 · 222 阅读 · 0 评论 -
[JLOI2015]管道连接
题目链接:[JLOI2015]管道连接我们先对每个特殊点集求出构成一颗斯坦纳树的最小代价。然后对于答案来说,是一颗最小代价的斯坦纳森林。所以我们最后枚举每种集合的斯坦纳树来组合成斯坦纳森林即可。要注意转移的合法性。当前集合要被拆分成几颗不同频率的生成树,并且这些频率的点被全部包含才可以转移。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int lon原创 2021-01-18 14:54:34 · 241 阅读 · 0 评论 -
Codeforces - Vowels
题目链接:Codeforces - Vowels考虑直接维护每个状态的合法个数。考虑使用sos dp维护。那么我们对于每个字符串,只需要对子集容斥一下即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=(1<<24);int n,dp[N],c原创 2021-01-06 10:14:53 · 178 阅读 · 0 评论 -
Jersey Number
题目链接:Jersey Number直接算有交集的不太好计算,我们可以选择计算不相交的,然后用总方案数减去。考虑不相交的,我们枚举每一种状态的区间,然后因为不相交,所以方案数为当前状态区间的方案数乘以当前状态取反的子集的方案数。对于一个状态的方案数,我们可以枚举右端点,对于左端点合法的一定最多只有16个。然后计数一下即可。对于一个状态的子集个数可以sos dp得到。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#includ原创 2021-01-06 09:01:52 · 622 阅读 · 0 评论 -
Codeforces - Jzzhu and Numbers
题目链接:Codeforces - Jzzhu and Numbers考虑反向枚举每个与运算不为0的集合个数,最后做差。然后我们可以枚举每个最后与起来的答案,我们就可以利用容斥来做。先求出每个集合的超集个数,最后利用二进制中1的个数来容斥。当只有一个1的时候减去这个答案,2个1的时候,由于计算了2次所以加上,然后3个1减去依次类推。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h原创 2021-01-03 20:15:07 · 242 阅读 · 0 评论 -
Codeforces - Bits And Pieces
题目链接:Codeforces - Bits And Pieces我们枚举每个 i ,然后按照二进制高位贪心,如果当前为0才需要管,我们只需要从后面看当前这个需要的二进制集合能否在后面找到二进制与起来,次大的下标。如果满足就加入答案,然后继续看低位。所以我们直接sos dp处理出来每种集合次大的位置。那么与起来也是一定满足的。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>原创 2021-01-03 12:08:35 · 214 阅读 · 0 评论 -
AT3913 XOR Tree
题目链接:AT3913 XOR Tree每次操作一条链显然不可做,我们尝试利用异或转化为两点间的操作。我们于是可以把边权转化为点权,对于每个点权为相邻边的异或值。然后我们可以发现每次操作一条链只有两个端点会改变。然后对于显然变成两点间的操作,显然对于相同权值的点,贪心只用一次操作即可。否则那么点权都是不一样的,直接状压dp。因为权值很小。令dp[s]为当前的点权集合为s的答案,我们可以发现如果一个集合异或为0那么才是有解的。因为每次异或两个相同的数,整个集合的异或是不会改变的。所以我们单独对集合原创 2021-01-03 10:57:59 · 185 阅读 · 0 评论 -
精简改良
题目链接:精简改良生成树dp。显然最后得到的一定是一颗生成树。我们定义 dp[i][s] 为当前生成树的集合为 s ,根节点为 i 。然后对枚举 s 的子集,让 i 和 子集当中某个点的连边计算贡献。但是无法确定集合之外的点在哪个集合当中,我们再强制子集当中的点不忘外连,显然不会影响答案。所以对当前边的贡献为:g[i][j] * popcount(j) * ( n - popcount(j) )AC代码:#pragma GCC optimize("-Ofast","-funroll-all-原创 2020-11-16 00:25:07 · 175 阅读 · 0 评论 -
交换茸角
题目链接:交换茸角如果可行。那么对于n个鹿,最多n-1次交换即可。否则,我们一定可以从中选出不相交的子集替换答案。然后枚举子集dp即可。判断是否可行,即sort之后两两是否合法。int i=(s-1)&s;i;i=(i-1)&s 这样即可枚举到s的所有子集,复杂度为 3 ^ nAC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int原创 2020-09-23 20:12:17 · 161 阅读 · 0 评论 -
Codeforces - Little Pony and Harmony Chest
题目链接:Codeforces - Little Pony and Harmony Chest因为值域很小,所以用到的质因子不会很多。所以我们对每个质因子状态压缩,使得一个质因子只会使用一次即可。然后Dp的时候记录转移方案。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const原创 2020-08-25 13:22:45 · 402 阅读 · 0 评论 -
HDU - 5418
题目链接:HDU - 5418状态dp,dp[i][s]为当前在 i 点,然后经过的状态为 s 的最短路。然后Dijkstra即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=17;int n,m,g[N][N],dp[N][1<<N],vis原创 2020-08-14 00:13:58 · 247 阅读 · 0 评论 -
排列
题目链接:排列显然爆搜复杂度过高,考虑用状态压缩dp优化。我们规定一个顺序放入数字,从小到大。那么 dp[s] 为当前放入数字的位置状态为 s 的最小值,因为是从小到大放,所以我们可以从二进制位找到当前放入的数字是谁,然后因为有一个绝对值,所以我们可以把绝对值拆开,分当前数字对之前已经放入的数字的贡献,和之后要放的数字的贡献,对于之后的数字,那么我们可以提前减去当前的数字那么之后看之间数字的贡献就可以直接加了。AC代码:#pragma GCC optimize("-Ofast","-funrol原创 2020-07-24 10:57:49 · 111 阅读 · 0 评论 -
Codeforces - Qualification Rounds
题目链接:Codeforces - Qualification Rounds显然,我们可以发现,如果n个人可以完成,那么选两个人也是一定有解的。所以按两个人计算即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long long...原创 2020-03-22 13:49:54 · 178 阅读 · 0 评论 -
Codeforces - Bicolorings
题目链接:Codeforces - Bicoloringsdp[i][j][k]为前i行,联通块个数为j,第i行状态为k的方案数。然后暴力转移即可。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>#define int long longusing names...原创 2020-03-14 11:51:10 · 152 阅读 · 0 评论 -
Codeforces - A Simple Task
题目链接:Codeforces - A Simple Task这个数据范围不难想到状压dp。我们令dp[x][s]为当前在点x,走过的状态为s的方案数。因为一个环会重复计数,所以我们规定计数时,起点是环的最小点。最后除2即可。因为是双向边,我们要防止一条边走过去又走回来,所以我们添加一个计数变量。AC代码:#include<bits/stdc++.h>using na...原创 2020-02-10 13:28:40 · 181 阅读 · 0 评论 -
Codeforces - Another Sith Tournament
题目链接:Codeforces - Another Sith Tournament这个数据,很明显的状压dp。我们令 dp[s]为当前状态为s,1获胜的最大概率。二进制01代表死没死。怎么转移呢?枚举两个不同的人取max。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h...原创 2020-02-07 15:41:13 · 299 阅读 · 0 评论 -
朋也与光玉
题目链接:朋也与光玉状压spfa即可,令 dp[i][s] 为当前在点i,走过灵玉集合为s 的最短路。AC代码:#pragma GCC optimize("-Ofast","-funroll-all-loops")#include<bits/stdc++.h>//#define int long longusing namespace std;const int N=1...原创 2020-01-31 11:26:45 · 199 阅读 · 0 评论 -
求长度
题目链接:求长度题目描述给定一幅n个点m条边的图和S个一定要经过的点,问从0号点出发,经过这S个点再回到0号点的最短路径长度是多少。输入描述:第一行一个整数T(T <= 2)表示数据组数。对于每组数据,第一行两个整数n,m表示点数和边数(1 <= n, m <= 100,000)。接下来m行,每行三个整数x, y, z(0 < x, y < n, 0 &l...原创 2020-01-15 20:13:05 · 326 阅读 · 0 评论 -
yyy loves Maths VII
题目描述一群同学在和yyy玩一个游戏每次,他们会给yyy n张卡片,卡片上有数字,所有的数字都是"幸运数字",我们认为第i张卡片上数字是ai每次yyy可以选择向前走ai步并且丢掉第i张卡片当他手上没有卡片的时候他就赢了但是呢,大家对"厄运数字"的位置布置下了陷阱,如果yyy停在这个格子上,那么他就输了(注意:即使到了终点,但是这个位置是厄运数字,那么也输了)现在,有些同学开始问:y...原创 2020-01-08 14:22:12 · 261 阅读 · 0 评论