[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名学生,方阵的行数 ...
随机推荐
- .NET平台系列22:.NET Core/.NET5/.NET6 对比 .NET Framework
系列目录 [已更新最新开发文章,点击查看详细] 在我的博客<.NET平台系列2 .NET Framework 框架详解>与 <.NET平台系列7 .NET Core 体系结构 ...
- 【题解】覆盖问题 BZOJ1052 HAOI2007 二分
题目描述 某 人在山上种了N棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定用 3个LL的正方形塑料薄膜将小树遮起来.我 ...
- Linux常用命令详解上
Linux常用命令详解上 目录 一.shell 二.Linux命令 2.1.内部命令与外部命令的区别 2.2.Linux命令行的格式 2.3.编辑Linux命令行的辅助操作 2.4.获得命令帮助的方法 ...
- Go语言深度比较值是否相等
Go语言深度比较值是否相等 需求描述: 我们在开发过程中经常会遇到一些需要比较值是否相等的场景,例如比较两个数组.结构体.Map.等,自己写这些代码比较繁琐,大部分时候这里都可以使用到反射reflec ...
- 基于HSI和局部同态滤波的彩色图像增强
简介 在图像采集过程中,由于光照环境或物体表面反光等原因会造成图像光照不均 .图像的光照不均会直接影响图像分析的结果.因此,对光照不均图像进行增强,消除光照的影响是光照不均图像处理中不可缺少的环节 . ...
- 27、myslq更改为不自动提交
27.1.说明: 默认情况下, MySQL启用自动提交模式(变量autocommit为ON).这意味着, 只要你执行DML操作的语句, MySQL会立即隐式提交事务(Implicit Commit). ...
- 深入学习Netty(3)——传统AIO编程
前言 之前已经整理过了BIO.NIO两种I/O的相关博文,每一种I/O都有其特点,但相对开发而言,肯定是要又高效又简单的I/O编程才是真正需要的,在之前的NIO博文(深入学习Netty(2)--传统N ...
- json串向后台传递数值自动四舍五入的问题
业务需求:传递前台输入的数据,数量要求是小数点(多条数据) 后台服务是使用asp.net写的. 问题:反序列化JSON时总是自动四舍五入. 原因:JSON反序列化的时候数据类型是以第一条数据的类型为准 ...
- UI自动化学习笔记- Selenium一些特殊操作的处理
一.特殊操作处理 1. 下拉选择框操作 1.1 如何操作下拉选择框 实现方式一 思路:先定位到要操作的option元素,然后执行点击操作 driver.find_element_by_css_sele ...
- Redis 过期时间解析
文章参考:<Redis 设计与实现>黄建宏 设置过期时间 通过 EXPIRE 或者 PEXPIRE 命令,客户端可以以秒或毫秒精度为数据库中的某个键设置生存时间 TTL (Time To ...