NOIP 2017 P3959 宝藏 (状态压缩DP板子)
题目的N这么小,当然是选择用状压DP啦! 等等,我好像不会状缩。。。。
首先,我们当然是要写状态转移方程了!!
那么,如果我们设 f[s] 状态s下,所要的最小花费,那么很显然有状态转移方程:
(s为总集合)
f[(1 << j) | s] = f[s] + num[i] * dis[i][j] (从 i 点走向 j点时)
其中,num表示之前已经走过的点的数量,dis表示从i到j的边的距离(这不就是题目要求吗)
很显然,这道题用DFS来做比较方便(跑图和回溯)
等等。
如果我们用不同的走法更新到同一个点,那么是否会影响到我们的更新呢? 显然是会的。
就比如,我们 1 -› 2 -› 3 -› 4 和 1 -› 3 -› 5 -› 2 - › 4 ,两种走法下,num的不同显然会给我们的更新带来不同的影响。
所以,上面的DP走法是有后效性的。
于是,我们要更新DP方程:
f[1 << j | s] = min( best + num[i] * dis[i][j]) , 其中 best 为上一层的最优解。
注意,起点不确定,怎么办? 当然是枚举起点啦!
#include <bits/stdc++.h>
using namespace std;
#define N 13
#define isdigit(c) ((c)>='0'&&(c)<='9')
#define min(a,b) ((a)<(b)?(a):(b)) inline int read(){
int x = , s = ;
char c = getchar();
while(!isdigit(c)){
if(c == '-')s = -;
c = getchar();
}
while(isdigit(c)){
x = (x << ) + (x << ) + (c ^ '');
c = getchar();
}
return x * s;
} int f[N][ << N][N];
int num[N], dis[N][N];
int n, m, limit;
int ans = (int)2e9; /*
状态转移方程:
对于当前的这个点j,如果他处在第 deth 层, 从第i号点转移到 j 则有
f[j][1 << j | s][deth] = best + num[i] * dis[i][j]
best 表示上一层最优解,dis表示i和j之间的距离
*/ void dfs(int s, int best, int deth){
if(best >= ans) return ; /*剪枝*/
if(s == limit) {
ans = min(ans, best); /*已经走完所有点*/
return ;
}
for(int i = ;i < n; i++){
if(!( << i & s)) continue; /*这个点还未走过,不能转移*/
for(int j = ;j < n; j++){
if(!( << j & s) && dis[i][j] < (int)2e9){
if(f[j][ << j | s][deth + ] > best + num[i] * dis[i][j]){
f[j][ << j | s][deth + ] = best + num[i] * dis[i][j]; /*进行转移*/
num[j] = num[i] + ; /*deth + 1, 因为j在i的下一层*/
dfs( << j | s, f[j][ << j | s][deth + ], deth + );
}
}
}
}
return ;
} int main(){
memset(dis, , sizeof(dis));
n = read(), m = read();
limit = ( << n) - ;
for(int i = ;i <= m; i++){
int x = read() - , y = read() - , w = read(); /*编号减一, 给状压用(2 ^ 0 才是 1)*/
dis[x][y] = dis[y][x] = min(dis[x][y], w);
}
for(int i = ;i < n; i++){
memset(num, , sizeof(num));
memset(f, , sizeof(f));
num[i] = ;
dfs( << i, , ); /*1 << i 把第i位设为 1*/
}
printf("%d\n", ans);
return ;
}
NOIP 2017 P3959 宝藏 (状态压缩DP板子)的更多相关文章
- 『宝藏 状态压缩DP NOIP2017』
宝藏(NOIP2017) Description 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的m 条道路和它们的长度. 小明决 ...
- 状态压缩dp(hdu2167,poj2411)
hdu2167 http://acm.hdu.edu.cn/showproblem.php?pid=2167 给定一个N*N的板子,里面有N*N个数字,选中一些数字,使得和最大 要求任意两个选中的数字 ...
- 最短路+状态压缩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 ...
随机推荐
- shell之路 shell核心语法【第三篇】运算
Bash 支持很多运算符,包括算数运算符.关系运算符.布尔运算符.字符串运算符和文件测试运算符. 原生bash不支持简单的数学运算,默认都是字符串操作,但是可以通过其他命令来实现 算数运算 expr. ...
- P2816 宋荣子搭积木
描述:https://www.luogu.com.cn/problem/P2816 saruka非常喜欢搭积木,他一共有n块积木.而且saruka的积木很特殊,只能一块块的竖着摞,可以摞很多列.说过s ...
- V - Can you answer these queries? HDU - 4027 线段树 暴力
V - Can you answer these queries? HDU - 4027 这个题目开始没什么思路,因为不知道要怎么去区间更新这个开根号. 然后稍微看了一下题解,因为每一个数开根号最多开 ...
- openCV从入门到放弃
与图像处理之间的关系,opencv的简介和使用定位 如题...因为偶然的机会需要用到图像处理,像我这么爱学习 并且动手能力又强的人怎么能没有心得笔记呢,哇哈哈哈.非要说的low逼点这玩意儿这玩意儿就是 ...
- mui日期设置与时钟样式时间设置
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- 使用Hystrix的插件机制,解决在使用线程隔离时,threadlocal的传递问题
背景 在我们的项目中,比较广泛地使用了ThreadLocal,比如,在filter层,根据token,取到用户信息后,就会放到一个ThreadLocal变量中:在后续的业务处理中,就会直接从当前线程, ...
- Python Web实战:Python+Django+MySQL实现基于Web版的增删改查
前言 本篇使用Python Web框架Django连接和操作MySQL数据库学生信息管理系统(SMS),主要包含对学生信息增删改查功能,旨在快速入门Python Web,少走弯路.效果演示在项目实战最 ...
- xml(3)
xml的解析方式:dom解析和sax解析 DOM解析 使用jaxp进行增删改查 1.创建DocumentBuilderFactory工厂 2.通过DocumentBuilderFactory工厂创建D ...
- Arrays.binarySearch的返回值
如果查找的值包含在数组中,返回搜索的第一个值的下标: 如果查找的值不在数组中,返回(-插入点-1):插入点即为第一个大于此查找值的元素下标 插入点 为将该值插入数组的那一点:即第一个大于此键的元素下标 ...
- HDU 2004 (水)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2004 题目大意: 给你成绩让你根据成绩打分解题思路: 简单的if...else 应用 需要注意是,if ...