HDU - 3001 Travelling 状压dp + 三进制 [kuangbin带你飞]专题二
终于刷完搜索专题了。
题意:给定n个城市,每个城市参观不能超过两次,两个城市之间有道路通过需要花费X,求通过能所有城市的最小花费。
思路:每个城市有三个状态0,1,2,可用三进制存储所有城市的访问状态。DP[i][j]表示当前状态为i,j是道路的最后一个城市。
如果j城市可以到达k城市,那么下一个状态就是next = i + bit[k],转移方程DP[next][k] = min(DP[next][k], DP[i][j] + cost[j][k]),cost[j][k]表示城市j到k的花费。
AC代码: 374ms
#include<cstdio> #include<vector> #include<algorithm> #include<cstring> #include<utility> using namespace std; typedef pair<int, int> PI; const int inf = 0x3f3f3f3f; const int maxn = 60000; int num[maxn][15], bit[15], cost[15][15], dp[maxn][15]; void init() { bit[0] = 1; for(int i = 1; i <= 10; ++i) bit[i] = bit[i - 1] * 3; for(int i = 0; i < bit[10]; ++i) { int x = i; for(int j = 0; j < 10; ++j) { num[i][j] = x % 3; x /= 3; } } } int main() { init(); int n, m; while(scanf("%d%d", &n, &m) == 2) { memset(cost, -1, sizeof(cost)); int x, y, c; for(int i = 0; i < m; ++i) { scanf("%d%d%d", &x, &y, &c); if(cost[x-1][y-1] == -1) { cost[x-1][y-1] = cost[y-1][x-1] = c; } else { cost[x-1][y-1] = cost[y-1][x-1] = min(cost[x-1][y-1], c); //去重边 } } memset(dp, inf, sizeof(dp)); //初始化边界 for(int i = 0; i < n; ++i) { dp[ bit[i] ][i] = 0; } int ans = inf; for(int i = 0; i < bit[n]; ++i) { int flag = 1; for(int j = 0; j < n; ++j) { if(num[i][j] == 0) flag = 0; //当前状态有从未经过的点 if(dp[i][j] == inf) continue; for(int k = 0; k < n; ++k) { if(k == j || num[i][k] >= 2 || cost[j][k] == -1) continue; int walk = i + bit[k]; //转换到新的状态 dp[walk][k] = min(dp[walk][k], dp[i][j] + cost[j][k]); } } if(flag) { for(int j = 0; j < n; ++j) ans = min(ans, dp[i][j]); } } if(ans == inf) ans = -1; printf("%d\n", ans); } return 0; }
如有不当之处欢迎指出!
HDU - 3001 Travelling 状压dp + 三进制 [kuangbin带你飞]专题二的更多相关文章
- HDU 3001 Travelling ——状压DP
[题目分析] 赤裸裸的状压DP. 每个点可以经过两次,问经过所有点的最短路径. 然后写了一发四进制(真是好写) 然后就MLE了. 懒得写hash了. 改成三进制,顺利A掉,时间垫底. [代码] #in ...
- HDU 3001 Travelling (状压DP + BFS)
题意:有一个人要去旅游,他想要逛遍所有的城市,但是同一个城市又不想逛超过2次.现在给出城市之间的来往路费,他可以选择任意一个点为起点. 问逛遍所有城市的最低路费是多少. 析:用三进制表示每个城市的访问 ...
- Travelling(HDU3001+状压dp+三进制+最短路)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题目: 题意:n个城市,m条边,每条边都有一个权值,问你经过所有的城市且每条边通过次数不超过两次 ...
- HDU3001 Traveling (状压dp+三进制+Tsp问题总结)
(1)这道题最多可以走两次,所以有0, 1, 2三种状态,所以我们要用三进制 如果要用三进制,就要自己初始化两个数组, 一个是3的n次方,一个是三进制数的第几位的数字是什么 void init() { ...
- [kuangbin带你飞]专题二十二 区间DP
ID Origin Title 17 / 60 Problem A ZOJ 3537 Cake 54 / 105 Problem B LightOJ 1422 Hallowee ...
- [kuangbin带你飞]专题二十 斜率DP
ID Origin Title 20 / 60 Problem A HDU 3507 Print Article 13 / 19 Problem B HDU 2829 Lawr ...
- HDU - 3533 bfs [kuangbin带你飞]专题二
看了好久的样例才看懂. 题意:有一个人要从(0,0)走到(n,m),图中有k个碉堡,每个碉堡可以向某个固定的方向每隔t秒放一次炮,炮弹不能穿越另一个碉堡,会被阻挡.人在移动的过程中不会被炮弹打到,也就 ...
- HDU - 3085 双向BFS + 技巧处理 [kuangbin带你飞]专题二
题意:有两只鬼,一个男孩女孩被困在迷宫中,男孩每秒可以走三步,女孩只能1步,鬼可以两步且可以通过墙.问男孩女孩是否可以在鬼抓住他们之前会合? 注意:每秒开始鬼先移动,然后两人开始移动. 思路:以男孩和 ...
- HDU - 1067 Gap (bfs + hash) [kuangbin带你飞]专题二
题意: 起初定28张卡牌的排列,把其中11, 21, 31, 41移动到第一列,然后就出现四个空白,每个空白可以用它的前面一个数的下一个数填充,例如43后面的空格可以用44填充,但是47后面即 ...
随机推荐
- 面试必问的 volatile,你了解多少?
前言 Java中volatile这个热门的关键字,在面试中经常会被提及,在各种技术交流群中也经常被讨论,但似乎讨论不出一个完美的结果,带着种种疑惑,准备从JVM.C++.汇编的角度重新梳理一遍. vo ...
- 结合find和cp批量查找文件并复制到指定文件夹中
find . -name JA1_*001_027 | xargs -i cp {} F:/ 说明: . 表示当前文件夹及其子文件夹中查找 -name 指定待查找文件,可以使用通配符 F:/ 表示 ...
- maps.reg
^/(.*\.miaopai.com/stream/.*\.mp4\?.*) http://$1 ^/([[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{ ...
- records.config文件配置模板
# # # Process Records Config File # # <RECORD-TYPE> <NAME> <TYPE> <VALUE (till ...
- python监控微信报警
微信接口调用代码: #coding=utf8 import itchat from flask import Flask, request itchat.auto_login(enableCmdQR= ...
- lvs+keepalive构建高可用集群
大纲 一.前言 二.Keepalived 详解 三.环境准备 四.LVS+Keepalived 实现高可用的前端负载均衡器 一.前言 Keepalived使用的vrrp协议方式,虚拟路由 ...
- oracle用户与表空间操作
oracle系统用户sys,system , sysman, scott 使用system用户登录[username/password][@server][as sysdba|sysoper]eg: ...
- js结合方式:
1. 在页面中使用script标签,在标签中书写js代码.<head><script type="text/javascript"> alert(&q ...
- Html5五子棋
1.效果图 2.代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...
- VS下WPF自定义控件的基本步骤和基本代码实现
一.自定义控件的基本步骤: (本示例项目名称为:W:添加的自定义控件名称为) 1. 在"解决方案资源管理器"窗口的项目名上: 右击à添加à新建项(Ctrl+Shift+A) 2. ...