非常巧妙的 \(O(n^23^n)\) 做法。

题目的本质是要求一棵生成树,使得其每条边的长度与这条边的起点深度乘积的和最小。

我们使用状压 DP,考虑到当前状态与已经打通的点和深度有关,不妨设 \(f(S,x)\) 为当前所打通点集合为 \(S\),且当前树深度为 \(x\) 时的最小花费。状态转移方程

\[f(S,x)=\min_{S_0\subsetneq S}\left\{f(S_0,x-1)+x\sum_{u\in S \backslash S_0}\min_{v\in S_0}\{w(u,v)\}\right\}
\]

翻译成人话就是,枚举当前状态的真子集,作为第 \(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\) 为全集。

其他需要注意的点:

  1. 预处理出每个点能拓展出的集合。
  2. 为方便位运算,将所有点标号为 \(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]宝藏 题解的更多相关文章

  1. NOIP2017 宝藏 题解报告【状压dp】

    题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是 ...

  2. [NOIP2017]宝藏 状压DP

    [NOIP2017]宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖 ...

  3. 【比赛】NOIP2017 宝藏

    这道题考试的时候就骗了部分分.其实一眼看过去,n范围12,就知道是状压,但是不知道怎么状压,想了5分钟想不出来就枪毙了状压,与AC再见了. 现在写的是状压搜索,其实算是哈希搜索,感觉状压DP理解不了啊 ...

  4. [NOIP2017]宝藏 子集DP

    题面:[NOIP2017]宝藏 题面: 首先我们观察到,如果直接DP,因为每次转移的代价受上一个状态到底选了哪些边的影响,因此无法直接转移. 所以我们考虑分层DP,即每次强制现在加入的点的距离为k(可 ...

  5. NOIP2017宝藏 [搜索/状压dp]

    NOIP2017 宝藏 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘 ...

  6. 【NOIP2017】宝藏 题解(状压DP)

    题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nnn 个深埋在地下的宝藏屋, 也给出了这 nnn 个宝藏屋之间可供开发的m mm 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中 ...

  7. NOIP2017[提高组] 宝藏 题解

    解析 我们观察范围可以发现n非常的小,(一般来说不是搜索就是状压dp)所以说对于这题我们可以用记忆化搜索或者dp,我们发现起点不同那么最终答案也就不同,也就是说答案是跟起点有关的,于是我们便可以想到去 ...

  8. NOIP2017 - 宝藏

    LibreOJ链接 Description 给出一个\(n(n\leq12)\)个点\(m(m\leq1000)\)条边的带权无向图,求该图的一棵生成树,使得其边权×该边距根的深度之和最小. Solu ...

  9. NOIP2017 列队 题解报告【56行线段树】

    题目描述 Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n \times mn×m名学生,方阵的行数 ...

随机推荐

  1. 字节首推Java成长笔记:(原理+应用+源码+调优全都有)直接复盘

    今天这篇文章我为了帮助小伙伴们快速构建Java技术栈,这份笔记包含了Java技术点的答案,面经,笔记,希望大家看完可以在短期内容快速面试复盘,达到事半功倍! 本来想将文件上传到开源网站上去,但是文件太 ...

  2. 解决servlet响应乱码问题

    当我们使用servlet响应中文时,浏览器接收的内容就会乱码显示出来,原因是响应数据时使用的是utt-8编码,而浏览器解析响应用的的编码却不是utf-8,这样就会造成乱码. 解决办法: respons ...

  3. 你能说出多线程中sleep、yield、join的用法及sleep与wait区别?

    Object中的wait.notify.notifyAll,可以用于线程间的通信,核心原理为借助于监视器的入口集与等待集逻辑 通过这三个方法完成线程在指定锁(监视器)上的等待与唤醒,这三个方法是以锁( ...

  4. NOIP模拟测试17「入阵曲&#183;将军令&#183;星空」

    入阵曲 题解 应用了一种美妙移项思想, 我们先考虑在一维上的做法 维护前缀和$(sum[r]-sum[l-1])\%k==0$可以转化为 $sum[r]\% k==sum[l-1]\%k$开个桶维护一 ...

  5. 海量数据Excel报表利器——EasyExcel(开场篇)

    EasyExcel 简介篇 互联网的精髓就是共享,可以共享技术.共享经验.共享情感.共享快乐~ 很多年前就有这个想法了,从事IT行业时间也不短了,应该把自己工作和业余所学习的东西记录并分享出来,和有缘 ...

  6. Redis在linux系统中的优化

    通常来看,Redis开发和运维人员更加关注的是Redis本身的一些配置优化,例如AOF和RDB的配置优化.数据结构的配置优化等,但是对于操作系统是否需要针对Redis做一些配置优化不甚了解或者不太关心 ...

  7. FastApi持续更新

    ​ FastAPI 框架,高性能,易于学习,高效编码,生产可用 官方文档: https://fastapi.tiangolo.com FastAPI 是一个用于构建 API 的现代.快速(高性能)的 ...

  8. 低代码Paas开发平台可以本地实施吗

    低代码Paas开发平台可以本地实施吗?答案是肯定的.虽然低代码开发通常是以云端形式面向用户,也就是我们经常看到到aPaaS,而它也更加倾向于SaaS.但实际上,低代码开发平台是可以支持本地部署的,例如 ...

  9. Java运算中的类型转换

    类型转换 运算中,不同类型的数据先转化为同一类型,然后进行运算 public class Dome04 { public static void main(String[] args) { //int ...

  10. Https:Java代码设置使用证书访问Https

    设置证书进行访问或被访问操作 String keyStore = "keyStore的文件路径": String KEY_STORE_PWD = "1234"; ...