HDU 4511 小明系列故事——女友的考验 ( Trie图 && DP )
题意 : 给出编号从1 ~ n 的 n 个平面直角坐标系上的点,求从给出的第一个点出发到达最后一个点的最短路径,其中有两种限制,其一就是只能从编号小的点到达编号大的点,再者不能走接下来给出的 m 个限制路径,也就是其中有些路线无法走。
分析 : 把问题抽象一下就是用编号 1 ~ n 构造一个字符串,使得字符串不包含 m 个给出的子串,且构造的代价是最小的 ( 两点间距就是代价,也就是路长 )。那如果做了很多有关在 Trie图 || AC自动机上DP的题目,那这道题就使用很套路的方法就可以了。先将给出的 m 个路线丢去构建 Trie 图,然后定义 DP[i][j] = 在编号为 i 的点 且 在 Trie 图上编号为 j 的节点状态下,最短的路径长度是多少,则可得转移方程
DP[i+1][k] = min( DP[i+1][k], DP[i][j] + GetDis(i, k) ) 且 i+1 <= k <= n (保证编号从小到大)
其中 GetDis(i, k) 是坐标点 i 和 k 的距离、而且 Trie[j].Next[k].flag == 0 即在 Trie 图上 j 状态到 k 状态合法,并不会使其包含非法路径
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
using namespace std;
;
;
const double INF = 1e20;///不能使用 0x3f3f3f3f
int n, m;
pair<];
struct Aho{
struct StateTable{
int Next[Letter];
int fail, flag;
}Node[Max_Tot];
int Size;
queue<int> que;
inline void init(){
while(!que.empty()) que.pop();
memset(Node[].Next, , ].Next));
Node[].fail = Node[].flag = ;
Size = ;
}
inline void insert(int *s, int len){
;
; i<len; i++){
int idx = s[i];
if(!Node[now].Next[idx]){
memset(Node[Size].Next, , sizeof(Node[Size].Next));
Node[Size].fail = Node[Size].flag = ;
Node[now].Next[idx] = Size++;
}
now = Node[now].Next[idx];
}
Node[now].flag = ;
}
inline void BuildFail(){
Node[].fail = ;
; i<n; i++){
].Next[i]){
Node[Node[].Next[i]].fail = ;
que.push(Node[].Next[i]);
}].Next[i] = ;///必定指向根节点
}
while(!que.empty()){
int top = que.front(); que.pop();
Node[top].flag |= Node[Node[top].fail].flag;///注意了!!
; i<n; i++){
int &v = Node[top].Next[i];
if(v){
que.push(v);
Node[v].fail = Node[Node[top].fail].Next[i];
}else v = Node[Node[top].fail].Next[i];
}
}
}
}ac;
double GetDis(pair<int,int> &st, pair<int,int> &en)
{
double x1 = (double)st.first;
double x2 = (double)en.first;
double y1 = (double)st.second;
double y2 = (double)en.second;
return sqrt( (double)(1.0*x1-x2)*(double)(1.0*x1-x2) +
(double)(1.0*y1-y2)*(double)(1.0*y1-y2));
}
][];
inline void Solve()
{
; i<n; i++)
; j<ac.Size; j++)
dp[i][j] = INF;
dp[][ac.Node[].Next[]] = ;
; i<n-; i++){
; j<ac.Size; j++){
if(dp[i][j] < INF){
; k<n; k++){
int newi = k;
int newj = ac.Node[j].Next[k];
if(!ac.Node[ newj ].flag){
dp[newi][newj] = min(dp[newi][newj],
dp[i][j]+GetDis(Point[i], Point[k]));
}
}
}
}
}
double ans = INF;
; i<ac.Size; i++)
][i] < INF)
ans = min(ans, dp[n-][i]);
if(ans == INF) puts("Can not be reached!");
else printf("%.2lf\n", ans);
}
int main(void)
{
while(~scanf("%d %d", &n, &m)){
&& m==) break;
; i<n; i++)///这里我将编号 -1 了,也就是编号从 0 ~ n-1,所以下面操作都是按个编号来
scanf("%d %d", &Point[i].first, &Point[i].second);
];
ac.init();
while(m--){
int k;
scanf("%d", &k);
; i<k; i++){
scanf("%d", &tmp[i]);
tmp[i]--;///因为编号是 0 ~ n-1
}
ac.insert(tmp, k);
}ac.BuildFail();
Solve();
}
;
}
HDU 4511 小明系列故事——女友的考验 ( Trie图 && DP )的更多相关文章
- HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)
小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total ...
- HDU 4511 小明系列故事——女友的考验 (AC自动机+DP)
小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total ...
- HDU - 4511 小明系列故事――女友的考验(AC自己主动机+DP)
Description 最终放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候.女朋友告诉他.她在电影院等他,小明过来的路线必须满足给定的规则: 1.如果小明 ...
- HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)题解
题意:从 1 走到 n,要求所走路径不能出现给定的路径,求最短路 思路:因为要求不能出现给定路径,那么我可以求助ac自动机完成判断. 我们可以在build的时候标记哪些路径不能出现,显然下面这种表示后 ...
- HDU4511 小明系列故事——女友的考验 —— AC自动机 + DP
题目链接:https://vjudge.net/problem/HDU-4511 小明系列故事——女友的考验 Time Limit: 500/200 MS (Java/Others) Memor ...
- 小明系列故事――女友的考验 HDU - 4511 AC自动机+简单DP
题意:自己看题目,中文体面. 题解: 把所有不能走的路径放入AC自动机中. 然后DP[i][j]表示走到 i 这个点,且位于AC自动机 j 这个节点最短距离 然后直接DP即可.注意一点会爆int #i ...
- HDU4511 小明系列故事——女友的考验(AC自动机 + DP)
题目大概说有平面有n个点,从1点出发走到n点,每一步只能走到序号比当前更大的点且走的序列不能包含给定的m个序列中的任何一个,问1走到n的最短路. 用m个序列建个AC自动机,后缀包含整个序列的结点标记一 ...
- hdu4511小明系列故事——女友的考验(ac自动机+最短路)
链接 预处理出来任意两点的距离,然后可以顺着trie树中的节点走,不能走到不合法的地方,另开一维表示走到了哪里,依次来更新. 注意判断一下起点是不是合法. #include <iostream& ...
- HDU-4511 小明系列故事——女友的考验 floyd变种-标号递增最短路
题意:给定N个点,现在要求出从1号点到N号点的最短路.题目给的限制条件就是对于某条路径是不能够走的,但是可以选择某段路径走,另外就是所走的路径的标号必须是递增的. 分析:由于给定的是一些列的坐标点,这 ...
随机推荐
- 避免浏览器缓存JS
有时候更改了JS代码,但是浏览器内容不变,这样<script src="Scripts/myjs/Master.js?v"></script>引入JS就可以 ...
- 前端 CSS的选择器
什么是选择器.在一个HTML页面中会有很多很多的元素,不同的元素可能会有不同的样式,某些元素又需要设置相同的样式,选择器就是用来从HTML页面中查找特定元素的,找到元素之后就可以为它们设置样式了. 选 ...
- windows下安装mysql8并修改密码
MySQL下载地址:http://dev.mysql.com/downloads/mysql/ Windows下安装MySQL 我下的是最新版的MySQL,解压后,目录如下: 1.进入dos的命令行, ...
- (三)认识twisted reactor
一.reactor是单线程模型,简单粗暴,也就是说网络IO和我们的业务逻辑一般是在一个线程里,其中网络IO通过event loop的方式去异步执行,效率也很高.看下官网的这幅图,比较清晰 twiste ...
- 数位dp相关
经典的数位Dp是要求统计符合限制的数字的个数. 一般的形式是:求区间[n,m]满足限制f(1). f(2). f(3)等等的数字的数量是多少. 条件 f(i) 一般与数的大小无关,而与数的组成有关. ...
- Python 入门之数据类型之间的相互转换 以及 在编程中会遇到的数据类型的坑
Python 入门之数据类型之间的相互转换 以及 在编程中会遇到的数据类型的坑 1.数据类型总结: 可变,不可变,有序,无序 (1)可变的数据类型:list dict set (2)不可变的数据类型: ...
- 思维体操: HDU1008 Elevator
Elevator Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 解决nodejs环境下端口号被占用的方法
假设被占用的端口号是8081 1.进入cmd命令窗口 输入netstat -ano|findstr "8081" cmd窗口给我的信息尾部有一个和端口8081对应的PID值 '51 ...
- java调用webservice接口 几种方法
webservice的 发布一般都是使用WSDL(web service descriptive language)文件的样式来发布的,在WSDL文件里面,包含这个webservice暴露在外面可供使 ...
- Qt项目界面文件(.ui)及其作用(超详细)
http://c.biancheng.net/view/1820.html Qt 项目中,后缀为“.ui”的文件是可视化设计的窗体的定义文件,如 widget.ui.双击项目文件目录树中的文件 wid ...