[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名学生,方阵的行数 ...
随机推荐
- Python_Selenium 之PO模式的思想、优化思路
一.PO模式思想 PO模式是一种自动化测试设计模式,将页面定位和业务操作分开,也就是把对象的定位和测试脚本分开,从而提供可维护性. PO设计模式基础(页面作为类.元素对象作为属性.元素操作作为方法) ...
- 如果攻击者操控了 redirect_uri,会怎样?
读者在看这篇文章之前,请先了解 Oauth2.0 的 Authorization Code 授权流程,可以看 Authorization Code 授权原理和实现方法 在 Token Enpoint ...
- 使用ElementTree解析,操作xml
一.最近在实际工作中需要对一部分接口进行测试,接口的入参与出参都是xml格式的数据,所以用到了python内部模块ElementTree对xml进行解析,并根据实际需求操作xml数据 二.代码示例 # ...
- 八、Nginx的TCP/UDP调度器
nginx 1.9后才可以调用其他应用 1.9前只能调用web 部署nginx服务器----配置----起服务.验证 部署nginx服务器: [root@proxy ~]# yum –y instal ...
- JUC并发包与容器类 - 面试题(一网打净,持续更新)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- 选择合适Redis数据结构,减少80%的内存占用
redis作为目前最流行的nosql缓存数据库,凭借其优异的性能.丰富的数据结构已成为大部分场景下首选的缓存工具. 由于redis是一个纯内存的数据库,在存放大量数据时,内存的占用将会非常可观.那么在 ...
- MySQL:聊一聊数据库中的那些锁
在软件开发中,程序在高并发的情况下,为了保证一致性或者说安全性,我们通常都会通过加锁的方式来解决,在 MySQL 数据库中同样有这样的问题,一方面为了最大程度的利用数据库的并发访问,另一方面又需要保证 ...
- js关于数组的操作(合并数组、添加数组、循环等)
1. concat() 方法 concat() 方法用于连接两个或多个数组 var arr = new Array(3) arr[0] = "George" arr[1] = &q ...
- ubuntu开机卡在/dev/sda* clean
问题描述: ①Ubuntu通过再生龙从一台笔记本还原到另外一台笔记本(硬盘到硬盘),开机后卡在自检界面: ②备份前的笔记本为17年发布的笔记本,还原后的笔记本为2020款发布的笔记本 从网上搜了一大篇 ...
- Jenkins 凭证 Devops 的粘合剂
大家好,我是小猿来也,一个热衷于搞 Devops 自动化的 Java 程序猿. 万事具备,只欠东风.当我决定大搞特搞 Devops 的时候,Jenkins 凭证却傻傻分不清. 玩 Devops 的小伙 ...