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 ...
随机推荐
- Spring官网阅读(十八)Spring中的AOP
文章目录 什么是AOP AOP中的核心概念 切面 连接点 通知 切点 引入 目标对象 代理对象 织入 Spring中如何使用AOP 1.开启AOP 2.申明切面 3.申明切点 切点表达式 excecu ...
- python学习之break和continue在for循环中的使用(案例:打印出10以内的偶数,并且只要前三个偶数)
运行程序,break是整个程序都跳出 continue则表示跳过当前一次循环,然后继续执行循环
- 数据预处理 —— padding数据
1. 论Conv2d()里的padding和Conv2d()前padding的区别及重要性. 小生建议,尽量少用Conv2d()里的填充方式,换成自定义填充方式(强烈建议). 小生为何这样建议 ...
- 简单谈谈Spring的IoC
一.前言 这几天正在复习Spring的相关内容,同时想要对Spring的实现原理做一些深入的研究.今天看了看Spring中IoC的实现,找到了一篇非常详细的博客,研究了一个下午,看完之后唯一的感受 ...
- Redis 学习笔记(一) 字符串 SDS
SDS 简单动态字符串. SDS的结构: struct sdshdr{ int len;//记录BUF数组中已使用字节的数量 ,等于SDS所八寸字符串的长度 int free;//记录BUF数组中未使 ...
- Linux dts 设备树详解(一) 基础知识
Linux dts 设备树详解(一) 基础知识 Linux dts 设备树详解(二) 动手编写设备树dts 文章目录 1 前言 2 概念 2.1 什么是设备树 dts(device tree)? 2. ...
- 计算机组成及系统结构-第十章 输入输出(I/O)系统
输入输出(I/O)系统 一.概述 1.输入输出设备的编址 2.设备控制器(I/O接口)的基本功能 3.I/O设备数据传送控制方式 二.程序中断输入输出方式 1.中断的定义 2.中断的作用 3.中断的产 ...
- FZU2105 线段树 (按位操作)
题目: Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations: (元素和操作元素 < 16) Opera ...
- Python自动生成100以内加减乘除混合运算题
import random from random import choice ops = ('+','-','×','÷') ans = [] i=0 while i < 100 : op1 ...
- 🏃♀️点亮你的Vue技术栈,万字Nuxt.js实践笔记来了~
前言 作为一位 Vuer(vue开发者),如果还不会这个框架,那么你的 Vue 技术栈还没被点亮. Nuxt.js 是什么 Nuxt.js 官方介绍: Nuxt.js 是一个基于 Vue.js 的通用 ...