『宝藏 状态压缩DP NOIP2017』
<更新提示>
<第一次更新>
<正文>
宝藏(NOIP2017)
Description
参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的m 条道路和它们的长度。
小明决心亲自前往挖掘所有宝藏屋中的宝藏。但是,每个宝藏屋距离地面都很远, 也就是说,从地面打通一条到某个宝藏屋的道路是很困难的,而开发宝藏屋之间的道路 则相对容易很多。
小明的决心感动了考古挖掘的赞助商,赞助商决定免费赞助他打通一条从地面到某 个宝藏屋的通道,通往哪个宝藏屋则由小明来决定。
在此基础上,小明还需要考虑如何开凿宝藏屋之间的道路。已经开凿出的道路可以 任意通行不消耗代价。每开凿出一条新道路,小明就会与考古队一起挖掘出由该条道路 所能到达的宝藏屋的宝藏。另外,小明不想开发无用道路,即两个已经被挖掘过的宝藏 屋之间的道路无需再开发。
新开发一条道路的代价是:
\]
L代表这条道路的长度,K代表从赞助商帮你打通的宝藏屋到这条道路起点的宝藏屋所经过的 宝藏屋的数量(包括赞助商帮你打通的宝藏屋和这条道路起点的宝藏屋) 。
请你编写程序为小明选定由赞助商打通的宝藏屋和之后开凿的道路,使得工程总代 价最小,并输出这个最小值。
Input Format
第一行两个用空格分离的正整数 n,m,代表宝藏屋的个数和道路数。
接下来 m 行,每行三个用空格分离的正整数,分别是由一条道路连接的两个宝藏 屋的编号(编号为 1−n),和这条道路的长度 v。
Output Format
一个正整数,表示最小的总代价。
Sample Input
4 5
1 2 1
1 3 3
1 4 1
2 3 4
3 4 1
Sample Output
4
解析
简单概括题意:给出一副无向图,每条边都有一个权值且均未开通,先可以随便取一个起点,要开通一些边,使它成为一个连通图,开通一条边的代价为这条边的权值*起点到它的点的个数(起点也算),求最小代价。
数据范围\(N<=12\),基本上可以确定是状压\(DP\)了。我们直接最简单地设置状态:\(f[S]\)代表以及取的节点的状态为S的最小代价,那么目标状态就是\(f[(1<<n)-1]\)。
如果考虑递推求解的话,我们发现需要计算花费的深度会很难枚举,这就导致了\(DP\)顺序的问题,如果选择用记忆化搜索求解的话,会方便很多。
由于起点不是确定的,我们需要用一重循环来枚举起点,然后以\(1<<(root-1)\)为初始状态,对每一种情况进行一次记忆化搜索,记搜的大体思路如下:
1.对于状态\(S\),枚举一个点\(i\),满足\(i \in S\)
2.在枚举一个点\(j\),满足\(i,j\)有边相连且\(j \notin S\)
3.状态转移方程:\(f[S']=min{f[S]+depth[i]*dis[i][j]}\)
4.更新新加入的节点j的深度
5.搜索下一个状态\(S'\)
6.回溯还原节点j的深度
最后在每一种情况的目标状态中取个\(min\)就是最终的答案了,时间复杂度\(O(n^32^n)\)。
\(Code:\)
#include<bits/stdc++.h>
using namespace std;
const int N=15,M=10015,Smax=(1<<N)+20,INF=0x3f3f3f3f;
int n,m,dis[N][N],f[Smax],depth[N],ans=INF;
inline void input(void)
{
memset(dis,0x3f,sizeof dis);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v,val;
scanf("%d%d%d",&u,&v,&val);
dis[u][v]=dis[v][u]=min(dis[u][v],val);
}
}
inline void Search(int S)
{
for(int i=1;i<=n;i++)
{
if((1<<(i-1))&S)
{
for(int j=1;j<=n;j++)
{
if(not ((1<<(j-1))&S)&&(dis[i][j]<INF))
{
if(f[S|(1<<(j-1))]>f[S]+depth[i]*dis[i][j])
{
int temp=depth[j];
depth[j]=depth[i]+1;
f[S|(1<<(j-1))]=f[S]+depth[i]*dis[i][j];
Search(S|(1<<(j-1)));
depth[j]=temp;
}
}
}
}
}
}
inline void solve(void)
{
for(int root=1;root<=n;root++)
{
memset(f,0x3f,sizeof f);
memset(depth,0x3f,sizeof depth);
f[1<<(root-1)]=0;
depth[root]=1;
Search(1<<(root-1));
ans=min(ans,f[(1<<n)-1]);
}
}
int main(void)
{
input();
solve();
printf("%d\n",ans);
}
<后记>
『宝藏 状态压缩DP NOIP2017』的更多相关文章
- 『最短Hamilton路径 状态压缩DP』
状压DP入门 最短Hamilton路径 Description 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamil ...
- 最短路+状态压缩dp(旅行商问题)hdu-4568-Hunter
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4568 题目大意: 给一个矩阵 n*m (n m<=200),方格里如果是0~9表示通过它时要花 ...
- hoj2662 状态压缩dp
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- [知识点]状态压缩DP
// 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...
- HDU-4529 郑厂长系列故事——N骑士问题 状态压缩DP
题意:给定一个合法的八皇后棋盘,现在给定1-10个骑士,问这些骑士不能够相互攻击的拜访方式有多少种. 分析:一开始想着搜索写,发现该题和八皇后不同,八皇后每一行只能够摆放一个棋子,因此搜索收敛的很快, ...
- DP大作战—状态压缩dp
题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...
- 状态压缩dp问题
问题:Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Ev ...
- BZOJ-1226 学校食堂Dining 状态压缩DP
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MB Submit: 588 Solved: 360 [Submit][ ...
随机推荐
- Android进阶:五、RxJava2源码解析 2
上一篇文章Android进阶:四.RxJava2 源码解析 1里我们讲到Rxjava2 从创建一个事件到事件被观察的过程原理,这篇文章我们讲Rxjava2中链式调用的原理.本文不讲用法,仍然需要读者熟 ...
- Extjs在树上加右键菜单--2019-04-15
效果图如下: 使用规则:将监听加到按钮或树上,监听代码如下. 代码如下: listeners : { //节点单击事件 'rowcontextmenu' : function(view, record ...
- ARTS Challenge- Week 1 (2019.03.25~2019.03.31)
1.Algorithm - at least one leetcode problem per week(Medium+) 986. Interval List Intersections https ...
- 无线路由WMM,Short GI,AP隔离功能介绍(转)
无线路由器中有开启WMM.开启Short GI和开启AP隔离分别代表什么呢?这是我在我的TP-LINK无线路由器TL-WR841N中的无线高级设置中看到的三个选项,下面三点对这三项无线高级设置做了下解 ...
- OI暑假集训游记
莞中OI集训游记 Written BY Jum Leon. I 又是一载夏,本蒟蒻以特长生考入莞中,怀着忐忑的心情到了8月,是集训之际.怀着对算法学习的向往心情被大佬暴虐的一丝恐惧来到了 ...
- Docker安装ngnix使用ping报错
最近在学习docker时,由于docker维护的dockerHub远程仓库的镜像文件比普通的文件小得多,所以经常碰到的情况是,一般常用的命令,会出现no command的情况.今天安装ping的时候就 ...
- C#三目运算符
在编写项目的时候,会经常用到 if else 判断语句,但有些简单的判断或赋值,可以通过三目运算符来完成! 例如: int sex=0; string sexText=""; if ...
- 如何查看ubuntu系统版本信息
第一种方法: hadoop@master:~$ cat /proc/version Linux version 4.4.0-21-generic (buildd@lgw01-21):Linux内核版本 ...
- Python基础之面向对象3(继承)
一.继承相关概念 1.语法: 2.定义: 3.优缺点: 4.相关概念: 5.相关内置函数: 6.继承内存图: 7.多继承: 二.多态相关概念 1.定义及作用: 2.重写概念: 3.运算符重载: 定义: ...
- Ubuntu添加中文输入法
1.点击左上角Dash home 2.输入keyboard input methods 3.点击keyboard input methods,选择input methods,打钩. 4.点击下三角,选 ...