Problem Description
终于放寒假了,小明要和女朋友一起去看电影。这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则:
  1、假设小明在的位置是1号点,女朋友在的位置是n号点,则他们之间有n-2个点可以走,小明每次走的时候只能走到比当前所在点编号大的位置;
  2、小明来的时候不能按一定的顺序经过某些地方。比如,如果女朋友告诉小明不能经过1 -> 2 -> 3,那么就要求小明来的时候走过的路径不能包含有1 -> 2 -> 3这部分,但是1 -> 3 或者1 -> 2都是可以的,这样的限制路径可能有多条。
  这让小明非常头痛,现在他把问题交给了你。
  特别说明,如果1 2 3这三个点共线,但是小明是直接从1到3然后再从3继续,那么此种情况是不认为小明经过了2这个点的。
  现在,小明即想走最短的路尽快见到女朋友,又不想打破女朋友的规定,你能帮助小明解决这个问题吗?
Input
输入包含多组样例,每组样例首先包含两个整数n和m,其中n代表有n个点,小明在1号点,女朋友在n号点,m代表小明的女朋友有m个要求;
  接下来n行每行输入2个整数x 和y(x和y均在int范围),代表这n个点的位置(点的编号从1到n);
  再接着是m个要求,每个要求2行,首先一行是一个k,表示这个要求和k个点有关,然后是顺序给出的k个点编号,代表小明不能走k1 -> k2 -> k3 ……-> ki这个顺序的路径;
  n 和 m等于0的时候输入结束。

  [Technical Specification]
  2 <= n <= 50
  1 <= m <= 100
  2 <= k <= 5

Output
对于每个样例,如果存在满足要求的最短路径,请输出这个最短路径,结果保留两位小数;否则,请输出”Can not be reached!” (引号不用输出)。
【题目大意】n个点,从1~n,每次只能走序号比之前序号大的,并且不能出现规定的顺序,求1~n的最短路径
【解题思路】
规定的顺序可以看作AC自动机上的字符串,从一个节点到另外一个节点
因为如果上面的路径没有办法到达的话,就说明下面的路径也没有办法到达
之后,用dp去求
dp[ i ] [ j ]  表示现在位置在第 i 个节点同时已经走到了AC自动机上的节点 j ,即已经经过了对应的路径
然后枚举状态转移
dp [ k ] [ t r i e [ j ] [ k ] ]   =   m i n ( d p [ k ] [ t r i e [ j ] [ k ] ] ,   d p [ i ] [ j ]   +   d i s ( i ,   k ) ) 
从点 i 走到点 k ,AC自动机的节点从 j 到 k ,距离增加 dis( i ,j )
【注意】
数组的类型定义错误,改了一个小时QAQ
本来应该定义成double ,结果定义成了 i n t ,nmd

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int     MAXN = 6000;
const int     MAXM = 600;
const double  INF  = 1e18;
int     trie[600][60],cnt;
int     fail[600],val[600],n,m,k;
double  dp[60][600];
struct node
{double x, y;
}a[60];
void insert(double *v)
{int now = 0;for (int i = 1; i <=k; i++){int u = v[i];if (!trie[now][u]){trie[now][u] = ++cnt;}now = trie[now][u];}val[now]=1;
}
void get_fail()
{int now = 0;queue<int> q;for (int i = 1; i <=n; i++)if (trie[now][i]){fail[trie[now][i]] = 0;q.push(trie[now][i]);}while (!q.empty()){int u = q.front(); q.pop();if (val[fail[u]])val[u]=1;for (int i = 1; i <=n; i++){int v = trie[u][i];if (v){fail[v] = trie[fail[u]][i];q.push(v);}else{trie[u][i] = trie[fail[u]][i];}}}return;
}
double dis(int i, int j)
{double tmp = (a[i].x - a[j].x)*(a[i].x - a[j].x) + (a[i].y - a[j].y)*(a[i].y - a[j].y);return sqrt(tmp);
}
double v[600];
double solve()
{double minn = INF;for (int i = 1; i <= n; i++)for (int j = 0; j <= cnt; j++)dp[i][j] = INF;dp[1][trie[0][1]] = 0;for (int i = 1; i <= n; i++){for (int j = 0; j <= cnt; j++){if (dp[i][j]<INF){for (int k = i + 1; k <= n; k++)if (!val[trie[j][k]])dp[k][trie[j][k]] = min(dp[k][trie[j][k]], dp[i][j] + dis(i, k));}}}for(int i=0;i<=cnt;i++)minn = min(minn, dp[n][i]);return minn;
}
int main()
{while (scanf("%d%d", &n, &m) && n && m){cnt = 0;memset(trie, 0, sizeof(trie));memset(val, 0, sizeof(val));memset(fail, 0, sizeof(fail));for (int i = 1; i <= n; i++)scanf("%lf%lf", &a[i].x, &a[i].y);while(m--){scanf("%d", &k);for (int i = 1; i <= k; i++)scanf("%lf", &v[i]);insert(v);}get_fail();double ans = solve();if (ans >= INF)printf("Can not be reached!\n");elseprintf("%.2f\n", ans);}return 0;
}

View Code

转载于:https://www.cnblogs.com/rentu/p/11336071.html

【HDU 4511】小明系列故事——女友的考验(AC自动机+DP)相关推荐

  1. HDU - 4511 小明系列故事——女友的考验(AC自动机+dp)

    题目链接:点击查看 题目大意:小明在点 1 而小明的女朋友在点 n ,现在小明要去找女朋友,满足以下两个条件: 途径的序号满足严格递增 小明的女朋友给小明提出了 m 条路径是不允许走的 在满足上述两条 ...

  2. HDU 4511 小明系列故事——女友的考验 ( Trie图 DP )

    题意 :  给出编号从1 ~ n 的 n 个平面直角坐标系上的点,求从给出的第一个点出发到达最后一个点的最短路径,其中有两种限制,其一就是只能从编号小的点到达编号大的点,再者不能走接下来给出的 m 个 ...

  3. 小明系列故事——女友的考验

    Problem Description 终于放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候,女朋友告诉他,她在电影院等他,小明过来的路线必须满足给定的规则: ...

  4. hdu 4501 小明系列故事——买年货 多重背包

    小明系列故事--买年货                                                                          Time Limit: 500 ...

  5. hdu 4506 小明系列故事——师兄帮帮忙

    小明系列故事--师兄帮帮忙 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total ...

  6. HDU 4506 小明系列故事——师兄帮帮忙

    小明系列故事--师兄帮帮忙 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) To ...

  7. HDU 4501 小明系列故事——买年货

    小明系列故事--买年货 Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tota ...

  8. HDU 4528 小明系列故事——捉迷藏

    题目链接~~> 做题感悟:这题需要逆向思维,先预处理一下就好. 解题思路:先预处理一下将可以看到 D 与 E 的点标记一下,这样 bfs()遍历迷宫时就可以节省很多时间,还要注意:可以重复走走过 ...

  9. hdu 4528小明系列故事——捉迷藏

    题目:点击打开链接 宽搜.注意判重.判重导致比赛的时候错了两次. #include <cmath> #include <ctime> #include <iostream ...

最新文章

  1. 【poj3420】 Quad Tiling
  2. Iaas、Caas、Paas、Faas!选择正确的平台!
  3. 【Java】生成UUID
  4. 服务器虚拟化与虚拟容器,虚拟化与Docker
  5. Angular 内容投影 content projection 关于选择器问题的单步调试
  6. 华为手机30s桌面循环滑动_华为发飙了!麒麟820+双模5G,从2699元跌至2499元,超出消费者预期...
  7. PHP根据指定url生成二维码图片
  8. mysql zip 还原_mysql 压缩还原数据库
  9. linux进程状态d状态,linux – 进程永久停留在D状态
  10. PowerEdge r730xd 安装centos 6.7
  11. VisualGDB系列9:配置VS直接通过SSH方式访问Linux项目
  12. xp系统计算机不休眠设置,xp和win7系统怎么设置电脑不休眠详细教程
  13. 生物医学信号检测与处理实验3——1微电阻梁
  14. 木瓜蛋白酶改性金纳米粒修饰淀粉/二氧化硅复合微球/硒化镉/聚苯乙烯荧光二氧化硅微球的研究
  15. Linux 添加IPv6策略路由,26-IPv6策略路由配置
  16. python 主函数传参_Python函数传参详解
  17. Java 选择视频文件对话窗口
  18. [code] PTA 胡凡算法笔记 DAY003
  19. android开发包下载
  20. 海康威视接口在线调试

热门文章

  1. OSPF(Open Shortest Path First开放式最短路径优先)
  2. textField textView输入限制
  3. 读《大话设计模式》有感
  4. 深入理解Java虚拟机04--类结构文件
  5. Mysql (一)Mysql 数据库增删改查
  6. Gogs 0.11.19 发布,自助 Git 托管服务
  7. DOM4j读取XML文件(SAXReader)
  8. 发布Apworks应用开发框架(Alpha版本)
  9. Ajax Tutorials
  10. Qt 2D绘图之二:抗锯齿渲染和坐标系统