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号点的最短路.题目给的限制条件就是对于某条路径是不能够走的,但是可以选择某段路径走,另外就是所走的路径的标号必须是递增的. 分析:由于给定的是一些列的坐标点,这 ...
随机推荐
- 函数参数中经常见到的*args和**kwargs
在python中,这两个是python中的可变参数,*arg表示任意多个无名参数,类型为tuple;**kwargs表示关键字参数,为dict. 例如下面这个代码可以利用*args计算传入的n个数的平 ...
- C盘无损扩容(傻逼拯救者128G固态分两个盘)
下载DiskGenius.exe 进行拆分分区(我从d盘拆分出20G给c盘) 然后右键此电脑,管理->磁盘管理 选中刚分出来的20G空间指向到c盘
- 自定义SpringBoot启动控制台图标
使用过SpringBoot的小伙伴众所周知,在启动的过程中,在控制台会首先打印spring的图标以及版本号(这里以IDEA为例) 如果需要更改这个打印图标的话, 需要以下步骤: 1.打开SpringB ...
- API接口设计
1.场景描述 比如说我们要做一款APP,需要通过api接口给app提供数据.假设我们是做商城,比如我们卖书的.我们可以想象下这个APP大概有哪些内容: 1)首页:banner区域(可以是一些热门书籍的 ...
- [Vim] 01 凡人操作
历史评价 编辑器之神 一个凡人的自我修养 成神是不可能成神的,只能是先入个门,然后一点一点学 Vim 官网 三种模式 插入模式(注意看光标) 命令模式(注意看光标) 编辑模式(注意看光标) 其实还有一 ...
- Quartz任务调度的测试Demo1(含有配置文件的demo)
Quartz是一个作业任务调度的框架,所在项目组中“消息推送模块”使用到此框架,于是写个demo熟悉下quart的用法: 使用Spring框架来集成Quartz的任务调度任务. 1.搭建Spring框 ...
- select count(*) 底层到底干了啥?
作者:贾春生,http://dwz.win/myg SELECT COUNT( * ) FROM TABLE 是个再常见不过的 SQL 需求了. 在 MySQL 的使用规范中,我们一般使用事务引擎 I ...
- 状态压缩dp相关
状态压缩dp 状态压缩是设计dp状态的一种方式. 当普通的dp状态维数很多(或者说维数与输入数据有关),但每一维总 量很少是,可以将多维状态压缩为一维来记录. 这种题目最明显的特征就是: 都存在某一给 ...
- ECCV2014 Accepted paper
今天早上看到小伙伴们说ECCV2014结果出来了, 自己于是赶紧看了下, 感觉ECCV2014显著性的文章和以往的不太一样. 1.Salient Montages from Unconstrained ...
- 如何将DataTable转换成List<T>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...