[NOIp2017]宝藏 题解
非常巧妙的 \(O(n^23^n)\) 做法。
题目的本质是要求一棵生成树,使得其每条边的长度与这条边的起点深度乘积的和最小。
我们使用状压 DP,考虑到当前状态与已经打通的点和深度有关,不妨设 \(f(S,x)\) 为当前所打通点集合为 \(S\),且当前树深度为 \(x\) 时的最小花费。状态转移方程
\]
翻译成人话就是,枚举当前状态的真子集,作为第 \(x-1\) 层的状态,将真子集的补集作为当前 \(x\) 层的点,找到向第 \(x-1\) 层连边的最小花费之和(当然,还要保证 \(S_0\) 可以扩展到当前状态)。
初始:\(\forall 1\leq i\leq n,f(\{i\},0)=0\),其余为正无穷。目标:\(\min\limits_{1\leq i\leq n}\{f(U,i)\}\),其中 \(U\) 为全集。
其他需要注意的点:
- 预处理出每个点能拓展出的集合。
- 为方便位运算,将所有点标号为 \(0,\dots,n-1\)。
现在分析一下复杂度。两两点枚举连边复杂度为 \(O(n^2)\),枚举所有子集的子集复杂度为 \(\sum\limits_{k=0}^{n}C^k_n2^k=(1+2)^n=3^n\)(二项式定理),于是总复杂度 \(O(n^23^n)\)。
(还在题解区发现 \(O(n3^n)\) 做法的,太巨了
#include <bits/stdc++.h>
using namespace std;
const int N=12,M=1<<N,INF=0x3f3f3f3f;
int n,m,d[N][N],f[M][N],g[M];
int main()
{
scanf("%d%d",&n,&m);
memset(d,INF,sizeof(d));
for(int i=0;i<n;++i) d[i][i]=0;
for(int i=1,a,b,c;i<=m;++i)
{
scanf("%d%d%d",&a,&b,&c);
a--,b--; d[a][b]=d[b][a]=min(d[a][b],c);
}
for(int i=1;i<1<<n;++i)
for(int j=0;j<n;++j)
if(i>>j&1)
for(int k=0;k<n;++k)
if(d[j][k]!=INF)
g[i]|=1<<k; //预处理可扩展集合
memset(f,INF,sizeof(f));
for(int i=0;i<n;++i) f[1<<i][0]=0;
for(int i=1;i<1<<n;++i)
for(int j=i-1;j;j=(j-1)&i) //枚举真子集
if((g[j]&i)==i)
{
int cpl=i^j,cost=0; //cpl即是补集
for(int u=0;u<n;++u) //对于每个点,求最小
if(cpl>>u&1)
{
int tmp=INF;
for(int v=0;v<n;++v)
if(j>>v&1)
tmp=min(tmp,d[u][v]);
cost+=tmp;
}
for(int k=1;k<n;++k) f[i][k]=min(f[i][k],f[j][k-1]+k*cost); //更新
}
printf("%d",*min_element(f[(1<<n)-1],f[(1<<n)-1]+n));
return 0;
}
[NOIp2017]宝藏 题解的更多相关文章
- NOIP2017 宝藏 题解报告【状压dp】
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是 ...
- [NOIP2017]宝藏 状压DP
[NOIP2017]宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖 ...
- 【比赛】NOIP2017 宝藏
这道题考试的时候就骗了部分分.其实一眼看过去,n范围12,就知道是状压,但是不知道怎么状压,想了5分钟想不出来就枪毙了状压,与AC再见了. 现在写的是状压搜索,其实算是哈希搜索,感觉状压DP理解不了啊 ...
- [NOIP2017]宝藏 子集DP
题面:[NOIP2017]宝藏 题面: 首先我们观察到,如果直接DP,因为每次转移的代价受上一个状态到底选了哪些边的影响,因此无法直接转移. 所以我们考虑分层DP,即每次强制现在加入的点的距离为k(可 ...
- NOIP2017宝藏 [搜索/状压dp]
NOIP2017 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘 ...
- 【NOIP2017】宝藏 题解(状压DP)
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nnn 个深埋在地下的宝藏屋, 也给出了这 nnn 个宝藏屋之间可供开发的m mm 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中 ...
- NOIP2017[提高组] 宝藏 题解
解析 我们观察范围可以发现n非常的小,(一般来说不是搜索就是状压dp)所以说对于这题我们可以用记忆化搜索或者dp,我们发现起点不同那么最终答案也就不同,也就是说答案是跟起点有关的,于是我们便可以想到去 ...
- NOIP2017 - 宝藏
LibreOJ链接 Description 给出一个\(n(n\leq12)\)个点\(m(m\leq1000)\)条边的带权无向图,求该图的一棵生成树,使得其边权×该边距根的深度之和最小. Solu ...
- NOIP2017 列队 题解报告【56行线段树】
题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数 ...
随机推荐
- Idea快捷键大全(Windows)
Ctrl 快捷键 介绍 Ctrl + F 在当前文件进行文本查找 (必备) Ctrl + R 在当前文件进行文本替换 (必备) Ctrl + Z 撤销 (必备) Ctrl + Y 删除光标所在行 或 ...
- Nebula 基于 ElasticSearch 的全文搜索引擎的文本搜索
本文首发于 Nebula Graph 公众号 NebulaGraphCommunity,Follow 看大厂图数据库技术实践. 1 背景 Nebula 2.0 中已经支持了基于外部全文搜索引擎的文本查 ...
- JavaScript 中的延迟加载属性模式
传统上,开发人员在 JavaScript 类中为实例中可能需要的任何数据创建属性.对于在构造函数中随时可用的小块数据来说,这不是问题.但是,如果在实例中可用之前需要计算某些数据,您可能不想预先支付该费 ...
- 屏蔽国内app开屏广告接口的记录
脉脉: im-x.jd.com api.taou.com 虎扑: goblin.hupu.com 知乎(屏蔽此接口后,进入知乎会报一次错误,不影响正常使用) api.zhihu.com 豆瓣: api ...
- JavaScript 实现:输出斐波那契数列
问渠那得清如许,为有源头活水来. 想要保持自己的技术活力,最有效的手段就是通过不断地输入来提供足够的养分.我们也不必刻意追求高深的或者新鲜的知识点,通过对一个基础问题的全方位多维度解析,同样也会收获不 ...
- 《面试补习》- Java集合知识梳理
一.ArrayList ArrayList 底层数据结构为 动态数组 ,所以我们可以将之称为数组队列. ArrayList 的依赖关系: public class ArrayList<E> ...
- CentOS7日志管理工具 journalctl
1.简介 日志管理工具journalctl是centos7上专有的日志管理工具,该工具是从message这个文件里读取信息. Systemd统一管理所有Unit的启动日志.带来的好处就是,可以只用jo ...
- 什么是TCP和UDP?
1.什么是IP和TCP? Internet协议(IP)是Internet的地址系统,具有将数据包从源设备传递到目标设备的核心功能.IP是建立网络连接的主要方式,奠定了Internet的基础.IP不负责 ...
- drf-Request与Response
一.Request 在Rest Framework 传入视图的request对象已经不再是Django默认的HTTPResponse对象了,而是Rest Framework提供的Request类的对象 ...
- CentOS-yum安装Nginx
查看系统版本 $ cat /etc/redhat-release Nginx 不在默认的 yum 源中,使用官网的 yum 源 $ rpm -ivh http://nginx.org/packages ...