NOIP2017宝藏 [搜索/状压dp]】的更多相关文章

NOIP2017 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是,每个宝藏屋距离地面都很远, 也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路 则相对容易很多. 小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某 个宝藏屋的通道,通往哪个宝藏屋则由小明来决定. 在此基础上,小明还需要考虑如…
按层dp,f[i][j]表示已扩展i子集的节点当前在第j层的最小代价,预处理点集间距离即可. #include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define ll long long #define N 12 #define i…
洛谷题目传送门 Dalao的题解多数是什么模拟退火.DFS剪枝.\(O(3^nn^2)\)的状压DP之类.蒟蒻尝试着把状压改进了一下使复杂度降到\(O(3^nn)\). 考虑到每条边的贡献跟它所在的层有关,所以如果我们能够将一层的边一起加进去,计算就会方便许多.于是想办法把这个转移过程状压一下. 设\(f_{i,j}\)为当前已选点集为\(i\),下一层加入的点集为\(j\)时,新加入的所有点与原有点之间最小的边权之和.计算的具体实现,我们\(O(2^n)\)枚举\(i\),再枚举\(i\)的补…
题意: 思路:n<=12,考虑状压DP 生成树中深度相同的点可以一次性转移完毕 设dp[sta,i]为已转移完sta状态的点,当前深度为i的最小花费 dp[sta or v,i+1]=min(dp[sta,i]+f[sta,v]*(i+1)),其中v是sta关于全集(1<<n)-1的补集v1的一个子集,这一步需要枚举子集 考场上写的O(3^n*n^2),没有预处理f[sta,v]而是每次都算了一遍,有进一步优化的空间 ; ..,..]of int64; f:..,..]of int64;…
洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复杂 只是存状态有点难想到 思路 因为n最大为12 所以可以想到是状压 因为n<=12 所以可以用邻接矩阵存下图 枚举每个点作为起点开始DFS 注意每次DFS的初始化和赋值问题即可 代码 #include<iostream> #include<cstdio> #include<…
传送门 为什么感觉状压dp都好玄学……FlashHu大佬太强啦…… 设$f_{i,j}$表示当前选的点集为$i$,下一次要加入的点集为$j$时,新加入的点和原有的点之间的最小边权.具体的转移可以枚举$i$,然后枚举$i$的补集$j$,找出$j$的$lowbit_j$ 那么转移就是$$f_{i,j}=min\{f_{i,j-lowbit_j}+min\{dis[lowbit_j][i]\}\}$$ 据说这一部分的复杂度是$O(3^nn)$,因为$n$元素的所有子集的大小之和是$3^n$(然而我并不…
题目:https://www.luogu.org/problemnew/show/P3959 原来写了个不枚举起点的状压dp. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; ,M=(<<)+,INF=0x3f3f3f3f; int n,m,lm,b[N][N],d…
题目描述: 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是,每个宝藏屋距离地面都很远, 也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路 则相对容易很多. 小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某 个宝藏屋的通道,通往哪个宝藏屋则由小明来决定. 在此基础上,小明还需要考虑如何开凿宝藏屋之间的道路.…
题目链接 题意 : 每一颗子弹破坏了三个邻近的阳台.(第N个阳台是与第1个相邻)射击后后的生存的怪物都对主角造成伤害- 如此,直到所有的怪物被消灭,求怎样射击才能受到最少伤害. 思路 : 状压,数据不是很大,可以爆一爆,或者DFS下去就行,枚举每一种状态. #include <cstdio> #include <cstring> #include <iostream> #define oo 1 << 28 using namespace std ; ],dp…
$O(n*3^n)$好难想...还有好多没见过的操作 令$f[i][j]$表示最深深度为i,点的状态为j的最小代价,每次枚举状态$S$后,计算$S$的补集里的每个点与S里的点的最小连边代价,再$O(3^n)$枚举S补集的子集,$g[x]$表示补集里状态为x的点往S集合里的点连边的最小代价,然后转移的时候加上它就好. 但是$g[x]$怎么处理呢...处理不好就会变成$O(3^n*n^2)$了,当然也可以预处理,但是有更简单的方法.因为我们枚举补集的时候是按顺序的,当前状态去掉最低位的状态一定是算过…
一开始状态设计错了-- 设f[i][s]为当前与根节点联通状况为s,最深深度为i 转移的话枚举当前没有和根联通的点集,预处理出把这些点加进联通块的代价(枚举s中的点和当前点的连边乘以i即可),然后用没联通点的集合b去更新f[i+1][s|b]即可 位运算处理用类似lowbit的东西 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=15; int…
愤怒的小鸟 题目描述 Kiana 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 (0,0) 处,每次 Kiana 可以用它向第一象限发射一只红色的小鸟,小鸟们的飞行轨迹均为形如 y=ax^2+bx的曲线,其中 a,b是Kiana 指定的参数,且必须满足 a<0,a,b 都是实数. 当小鸟落回地面(即 x 轴)时,它就会瞬间消失. 在游戏的某个关卡里,平面的第一象限中有 n 只绿色的小猪,其中第 i 只小猪所在的坐标为 (xi​,yi​) . 如果某…
[NOIP2017]宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是,每个宝藏屋距离地面都很远, 也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路 则相对容易很多. 小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某 个宝藏屋的通道,通往哪个宝藏屋则由小明来决定. 在此基础上,小明还需要考虑…
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nnn 个深埋在地下的宝藏屋, 也给出了这 nnn 个宝藏屋之间可供开发的m mm 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是,每个宝藏屋距离地面都很远, 也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路 则相对容易很多. 小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某 个宝藏屋的通道,通往哪个宝藏屋则由小明来决定. 在此基础上,小明还需要考虑如何开凿宝藏屋…
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是,每个宝藏屋距离地面都很远, 也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路 则相对容易很多. 小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某 个宝藏屋的通道,通往哪个宝藏屋则由小明来决定. 在此基础上,小明还需要考虑如何开凿宝藏屋之间的道路.…
正解:状压$dp$ 解题报告: 传送门$QwQ$ $8102$年的时候就想搞这题了,,,$9102$了$gql$终于开始做这题了$kk$ 发现有意义的状态只有当前选的点集和深度,所以设$f_{i,j}$表示当前深度为$i$,选了的点集状态为$j$. 然后转移就$f_{i,S}=min(f_{i-1,S_0}+cost)$,其中$S_0$为$S$的子集,$cost$为$S\ xor\ S_0$中的所有点和$S_0$的连边乘以$i$. 正确性显然?然后说下就,这里是并没有限制一定是和第$i-1$层的…
这题太难了...看了30篇题解才整明白到底咋回事... 核心思想:状压dp+搜索+容斥 首先我们分析一下,对于一个4*7的棋盘,低点的个数至多只有8个(可以数一数) 这样的话,我们可以进行一个状压,把所有的低点压进来 然后我们从小到大枚举所有数,转移即可 记状态f[i][j]表示到了第i个数,低点的状态为j的方案数 那么在转移的时候,有两个转移方向: ①.如果第i个数放在低点上,那么我们可以枚举所有的低点k,如果低点没有在状态里,有: dp[i][j|(1<<k)]+=dp[i-1][j] ②…
时隔多年终于把这道题锅过了 数据范围显然用搜索剪枝状压dp. 可以记还有哪些点没到(或者已到了哪些点).我们最深已到的是哪些点.这些点的深度是多少,然后一层一层地往下推. 但其实是没必要记最深的那一层的,只要强行装作每次更新都是用最深的深度更新就可以.这样的话,虽然会有很多情况偏大,但是能正确更新的情况其实是都已经包括了. 因为你如果想以当前状态去更新,但用的还不是最深一层的点的话,干脆就可以在之前你想用那个点处于最后一层的时候去更新. 代码写的很捉急..最后常数也很捉急... #include…
之前写了一份此题关于模拟退火的方法,现在来补充一下状压dp的方法. 其实直接在dfs中状压比较好想,而且实现也很简单,但是网上有人说这种方法是错的...并不知道哪错了,但是就不写了,找了一个正解. 正解的区别在于状态,(树高是啥意思),每次都是从当前状态的子集转移过来.这里用到了快速枚举子集的操作,很值得写一下. 题干: 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nnn 个深埋在地下的宝藏屋, 也给出了这 nnn 个宝藏屋之间可供开发的m mm 条道路和它们的长度. 小明决心…
题目描述 小$w$偶然间见到了一个$DAG$. 这个$DAG$有$m$层,第一层只有一个源点,最后一层只有一个汇点,剩下的每一层都有$k$个节点. 现在小$w$每次可以取反第$i(1<i<n-1)$层和第$i+1$层之间的连边.也就是把原本从$(i,k_1)$连到$(i+1,k_2)$的边,变成从$(i,k_2)$连到$(i+1,k_1)$. 请问他有多少种取反的方案,把从源点到汇点的路径数变成偶数条? 答案对$998244353$取模. 输入格式 一行两个整数$m,k$. 接下来$m-1$行…
「状压DP」「暴力搜索」排列 题目描述: 题目描述 给一个数字串 s 和正整数 d, 统计 sss 有多少种不同的排列能被 d 整除(可以有前导 0).例如 123434 有 90 种排列能被 2 整除,其中末位为 2 的有 30 种,末位为 4 的有 60 种. 输入格式 输入第一行是一个整数 TTT,表示测试数据的个数,以下每行一组 s 和 d,中间用空格隔开.s 保证只包含数字 0,1,2,3,4,5,6,7,8,9 输出格式 每个数据仅一行,表示能被 d 整除的排列的个数. 输入输出样例…
题面 传送门:https://www.luogu.org/problemnew/show/P3959 Solution 这道题的是一道很巧妙的状压DP题. 首先,看到数据范围,应该状压DP没错了. 根据我们之前状压方程的设计经验,我们很快就能设计出这样的方程: 设f[i][j]表示用到第i个元素,当前连接状态为j的开销的min 但是我们很快就会发现,这个方程没法转移,因为随着连接方案的不同,新插入的点的K值会不同. 怎么办呢? 这时候我们可以重新设计一个巧妙的的状态. 重新阅读题目,我们可以发现…
POJ3279http://poj.org/problem?id=3279 题意:黑白的板,每次选择一个十字形翻转(十字板内黑白互换,若是边界则不管),求最小将原图变为全白的策略. 这是一道对于每个格子的选择会对相邻格子造成影响的问题,回顾一下,这个问题和状压dp解决的问题的条件基本一致,而状压dp是求总方案数,这个是求最佳方案 操作上:状压dp,通过对第一行的状态进行枚举,然后对后面的每一行进行相应枚举,记录方案数,类似的,这道题,通过对第一行的状态进行枚举,然后对后面的每一行进行的操作是--…
链接 : Here! 思路 : 状压DP. 开始想直接爆搜, T掉了, 然后就采用了状压DP的方法来做. 定义$f[S]$为集合$S$的最小代价, $dis[i]$则记录第$i$个点的"深度", 所以说边$E{[i, j]}$ 的工程代价就为$dis[i] * E{[i, j]}$, 因此可以得到状态转移方程 : 初始状态(假设以$i$作为起点) : $dis[i] = 1$, $f[1 << (i - 1)] = 0$, $dis[k] = INF (k != i, k…
简单的状压DP,和NOIP2017 Day2 找宝藏 代码几乎一样.(比那个稍微简单一点) f[i][j] ,i代表点的状态,j是当前选择的点,枚举上一个选到的点k 然后从f[i-(1<<(j-1))][k]转移到f[i][j]即可 方程f[i][j]=max(f[i][j],[k]+B[k][j]+A[j]); 注意的点1.开longlong 2.数据不保证X[i]和Y[i]都不同,也不保证X[i]不等于Y[i],这里很坑要加特判. #include<cstdio> #inclu…
前言 复习笔记第4篇.CSP RP++. 引用部分为总结性内容. 0--P1433 吃奶酪 题目链接 luogu 题意 房间里放着 \(n\) 块奶酪,要把它们都吃掉,问至少要跑多少距离?一开始在 \((0,0)\) 点处. \(n\leq 15\) ,保留两位小数. 思路 为啥状压第一题是绿题啊.这么水了吗,为啥我还不会( 令 \(f[i][s]\) 表示从点 \(i\) 出发,遍历集合为 \(S\) 的最小值,枚举其他点进行转移.预处理边界 \(f[i][s]=0\) (\(S\) 为除了第…
数据最多14个有宝藏的地方,所以可以想到用状压dp 可以先预处理出每个i到j的路径中最小权值的最大值dis[i][j] 本来想用Floyd写,无奈太弱调不出来..后来改用spfa 然后进行dp,这基本是货郎担问题(TSP),状压中挺常出现的问题 f[s][i]表示状态s下到第i个有宝藏的地方,是否能拿到所有s中的宝藏 当然最后还要考虑dis[id[i]][1]是否大于s状态下的宝藏数,取较小值就是答案了 跑了48ms,优化一下应该可以更快.. #include<stdio.h> #includ…
一.题目 Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上.下.左.右,以及左上.左下.右上.右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N) Output 方案数 Sample Input 3 2 Sample Output 16 原题链接→_→bzoj1087: [SCOI2005]互不侵犯King 二.题目分析 其实我们可以…
第一题: 给出一个长度不超过100只包含'B'和'R'的字符串,将其无限重复下去. 比如,BBRB则会形成 BBRBBBRBBBRB 现在给出一个区间[l,r]询问该区间内有多少个字符'B'(区间下标从1开始)   [1<=l,r<=1e18]解:  没想到第一题这么水.直接前缀和+mod就可以了,再判一下边界.注意1e18不需要高精度.long long 有9*10^18. #include<iostream> #include<cstdio> #include<…
题意:给一个n*m的格子,格子中有一些数,如果是正整数则为到此格子的花费,如果为-1表示此格子不可到,现在给k个宝藏的地点(k<=13),求一个人从边界外一点进入整个棋盘,然后拿走所有能拿走的宝藏的最小花费,如果一次不能拿走所有能拿到的或者根本拿不到任何宝藏,输出0. 解法:看到k的范围应该想到状态压缩,将每个格子都看成一个点,再新建两个点,一个表示边界外的起点,用0表示,一个表示边界外的终点,用n*m+1表示,然后相互建边,建有向边,边权为终点格子的花费值,(其实都不用建边,直接跑最短路也行)…