NOIP2017 D2T2 宝藏
其实就是一道暴力搜索题……只是需要一个状态压缩的剪枝比较难想而已
这根本不叫dfs!只是一个递归而已……开始就被dfs坑了
思路:
首先一个基本的预处理
数据范围n≤12,m≤5000,说明肯定有很多没用的边,在读入的时候预处理掉就可以了,另外n很小可以用邻接矩阵存图访问快
解法一:暴力搜索
直接暴力搜索,开一个数组记录一个点有没有被访问过。每到一个状态,从访问过的点到未访问过的点引边算代价,递归枚举一下即可。但此方法时间复杂度较大,大约为O(n^n)?(没有仔细算),n<=8差不多能过
期望得分:70分(然而实际得分只有60分)
解法二:状态压缩剪枝
解法一很显然有很多无用的操作,那么如何进行剪枝呢?
答案是:状态压缩(这也是博主第一次接触到这个)
状态压缩就是用一个01串表示一个状态
每一位0代表未选择,1代表被选择
实际操作中我们通常用二进制数来表示状态压缩,为了方便我们用倒序(最右边是第一个,紧挨着是第二个,以此类推)
比如01串010001就可以表示第1个、第5个元素被选择了
然后使用位运算加速
选择某个元素(加入状态):x=x|(1<<(i-1))
判断第i个元素有没有选择:x&(1<<(i-1))(真:被选择;假:未选择)
那么,开一个数组f[i]表示当前根节点下状态为i的已搜索到的最小代价
这样我们在搜索时,如果这一次更新的代价比当前状态下以搜索到的最小代价要大(更新的代价>f[i]),说明这次搜索一定不是最优解,就不用进行递归算到最后
剪枝到底能减掉多少我不知道……但这一题可以AC了
期望得分:100分
AC代码:
#include<cstdio>
#include<climits>
#include<cstring>
using namespace std;
int f[];//状态压缩答案存储
int tu[][];//邻接矩阵存图
int n,m;//点、边数
int depth[];//每个点深度
void find(int x)
{
for(int i=;i<=n;i++)
if(x&(<<(i-)))//编号为i的点访问过,从它开始更新
for(int j=;j<=n;j++)
if((!(x&(<<(j-))))&&tu[i][j]!=INT_MAX)//编号为j的点未访问过且i,j间有边相连
if(f[x]+depth[i]*tu[i][j]<f[x|(<<(j-))])//连i,j后答案比之前找出答案小则继续寻找,否则一定不是最优解,不用递归
{
f[x|(<<(j-))]=f[x]+depth[i]*tu[i][j];
depth[j]=depth[i]+;
find(x|(<<(j-)));
}
}
int min(int a,int b){return a<b?a:b;}
int main()
{
for(int i=;i<=;i++)
for(int j=;j<=;j++)
tu[i][j]=INT_MAX;
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
tu[u][v]=tu[v][u]=min(tu[u][v],w);//存最小边
}
int ans=INT_MAX;//保存答案
for(int i=;i<=n;i++)//对每个点暴力枚举
{
for(int j=;j<=(<<n)-;j++)
f[j]=INT_MAX;//每一个根节点都要初始化f[]
f[<<(i-)]=;
depth[i]=;//根节点深度为1
find(<<(i-));
ans=min(ans,f[(<<n)-]);
}
printf("%d\n",ans);
return ;
}
NOIP2017 D2T2 宝藏的更多相关文章
- NOIP2017 D2T2宝藏
考场上写的prim一遍过了大样例也没想什么别的,反例也没举出来. 后来才知道由于要乘上深度所以无法贪心. 正解是状压但我不会,考后一个爆搜碾过去了. 心凉. #include<bits/stdc ...
- #333. 【NOIP2017】宝藏
#333. [NOIP2017]宝藏 http://uoj.ac/problem/333 1.错误的$n^42^n$做法: dp[s]表示当前的点集为s,然后从这些点中选一个做起点i,然后枚举边,然后 ...
- 【NOIP2017】宝藏(状态压缩,动态规划)
[NOIP2017]宝藏(状态压缩,动态规划) 题面 洛谷 题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路 ...
- 「NOIP2017」宝藏
「NOIP2017」宝藏 题解 博客阅读效果更佳 又到了一年一度NOIPCSP-S 赛前复习做真题的时间 于是就遇上了这道题 首先观察数据范围 \(1 \le n \le 12\) ,那么极大可能性是 ...
- [NOIP2017 TG D2T2]宝藏(模拟退火)
题目大意:$NOIPD2T2$宝藏 题解:正常做法:状压DP .这次模拟退火,随机一个排列,$O(n^2)$贪心按排列的顺序加入生成树 卡点:没开$long\;long$,接受较劣解时判断打错,没判$ ...
- [NOIP2017 TG D2T2]宝藏
题目大意:给定一个有重边,边有权值的无向图.从某一个点出发,求到达所有的点需要的最少费用,并且限制两点之间只有一条路径.费用的计算公式为:所有边的费用之和.而边$x->y$的费用就为:$y$到初 ...
- 【NOIP2017】宝藏
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 \(n\) 个深埋在地下的宝藏屋, 也给出了这 \(n\) 个宝藏屋之间可供开发的 \(m\) 条道路和它们的长度. 小明决心亲自前往挖掘 ...
- 【NOIP2017】宝藏 题解(状压DP)
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nnn 个深埋在地下的宝藏屋, 也给出了这 nnn 个宝藏屋之间可供开发的m mm 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中 ...
- 【NOIP2017】 宝藏 状压dp
为啥我去年这么菜啊..... 我现在想了$20min$后打了$10min$就过了$qwq$. 我们用$f[i][j]$表示当前深度为$i$,访问了状态$j$中的所有点的最小代价. 显然$f[i][j] ...
随机推荐
- JS实现数组排序:升序和降序
如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序.即 a 和 b 是两个将要被比较的元素: 如果 compareFunction(a, b) 小于 0 ,那么 a 会 ...
- 关于maven项目 启动页面报错 The type java.io.ObjectInputStream cannot be resolved.
这种情况,要修改jdk版本,默认jdk选择 jdk不选jre windows---->perference---->java----->installes jres-----> ...
- spss中如何处理极端值、错误值
spss中如何处理极端值.错误值 spss中录入数据以后,第一步不是去分析数据,而是要检验数据是不是有录入错误的,是不是有不合常理的数据,今天我们要做一个描述性统计,进而查看哪些数据是不合理的.下面是 ...
- Oracle不完全恢复-主动恢复和incarnation/RMAN-20208/RMAN-06004
12.3 主动恢复 主动不完全恢复是将数据库“撤回”到从前的传统方法,主要用来撤销认为修改.一般需要先判断PIT点的时间或SCN --1 重启db到mount状态 --2 用restore将所有的数据 ...
- 【Java安全】关于Java中常用加密/解密方法的实现
安全问题已经成为一个越来越重要的问题,在Java中如何对重要数据进行加密解密是本文的主要内容. 一.常用的加密/解密算法 1.Base64 严格来说Base64并不是一种加密/解密算法,而是一种编码方 ...
- sql语句经验
1:拼接字段模糊查询 where aaa(字段) not like CONCAT(DATE_FORMAT(new(),"%Y-%m-%d"),'%完成%'): 2:备份表中数据导 ...
- MSSQL注入--反弹注入
明明是sql注入的点,却无法进行注入,注射工具拆解的速度异常的缓慢,错误提示信息关闭,无法返回注入的结果,这个时候你便可以尝试使用反弹注入, 反弹注入需要依赖于函数opendatasource的支持, ...
- HTTP 常见相应状态码及含义
1xx:信息 100 Continue 服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求. 101 Switching Protocols 服务器转换协议:服务器将 ...
- [转帖]16nm国内最先进 兆芯展示x86 KX-6000八核处理器
16nm国内最先进 兆芯展示x86 KX-6000八核处理器 https://www.cnbeta.com/articles/tech/847125.htm 在近日的2019北京国际互联网科技博览会暨 ...
- vue点击除了某组件本身的其它地方, 隐藏该组件的方法
点击emoji表情标签, 出现标签组件,点击其它地方, 改组件消失的效果; <template> <div class="writeZoon"> <d ...