HDU 4511 (AC自动机+状态压缩DP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4511
题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2->N,但是某些段路径(注意不是某些条)是被禁止的。问从1->N的最短距离。
解题思路:
AC自动机部分:
如果只是禁掉某些边,最短路算法加提前标记被禁的边即可。
但是本题是禁掉指定的路段,所以得边走边禁,需要一个在线算法。
所以使用AC自动机来压缩路段,如禁掉的路段是1->2->3,那么insert字符串(123) ,注意点只有1~50,所以0~50用ASCII 压缩成字符串即可。
这样就能够完成禁止路段的在线状态转移。
状态压缩DP部分:
其实就是手艹一个两点之间的最短路。dp[i][j]表示在地点i,当前字符是j的状态。
初始化:fill(&dp0][0],&dp[maxn-1][maxp-1],inf),inf=1e12,double的inf很头疼,memset是不能用的。
边界:首先找下出发点在pool中的位置,s=root->next[0],如果s被禁,那么就不用算了。否则dp[0][s]=0;
方程: dp[k][t]=min(dp[k][t],dp[i][j]+dist(i,k))
答案:min(dp[n-1][0..cnt])
解释下方程,其中for(0...i...n-1),for(i+1...k....n) ,枚举两个点。
然后就是中间多出的AC自动机的状态压缩for(0....j....cnt),负责打出所有的路径转移状态。
#include "cstdio"
#include "cstring"
#include "string"
#include "iostream"
#include "queue"
#include "math.h"
using namespace std;
#define maxn 55
#define maxp 10*100
#define inf 1e12
struct Point
{
double x,y;
}P[maxn];
struct Trie
{
Trie *next[maxn],*fail;
int cnt;
}pool[maxp],*root,*sz;
int pre,now;
double dp[][maxp];
Trie *newnode()
{
Trie *ret=sz++;
memset(ret->next,,sizeof(ret->next));
ret->fail=;
ret->cnt=;
return ret;
}
void init()
{
sz=pool;
root=newnode();
}
void Insert(string str)
{
Trie *pos=root;
for(int i=;i<str.size();i++)
{
int c=str[i];
if(!pos->next[c]) pos->next[c]=newnode();
pos=pos->next[c];
}
pos->cnt++;
}
void getfail()
{
queue<Trie *> Q;
for(int c=;c<maxn;c++)
{
if(root->next[c])
{
root->next[c]->fail=root;
Q.push(root->next[c]);
}
else root->next[c]=root;
}
while(!Q.empty())
{
Trie *x=Q.front();Q.pop();
for(int c=;c<maxn;c++)
{
if(x->next[c])
{
x->next[c]->fail=x->fail->next[c];
x->next[c]->cnt+=x->fail->next[c]->cnt;
Q.push(x->next[c]);
}
else x->next[c]=x->fail->next[c];
}
}
}
double dist(Point a,Point b) {return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
int main()
{
//freopen("in.txt","r",stdin);
int n,m,k,p;
while(scanf("%d%d",&n,&m)!=EOF&&n)
{
init();
for(int i=;i<n;i++) scanf("%lf%lf",&P[i].x,&P[i].y);
for(int i=;i<=m;i++)
{
scanf("%d",&k);
string tt;
for(int i=;i<=k;i++)
{
scanf("%d",&p);
tt.push_back(p-);
}
Insert(tt);
}
getfail();
int s=root->next[]-pool;
if(root->next[]->cnt) printf("Can not be reached!\n");
else
{
int cnt=sz-pool;
fill(&dp[][],&dp[][maxp-],inf);
dp[][s]=;
for(int i=; i<n-; i++)
{
for(int j=; j<cnt; j++)
{
Trie *pos=pool+j;
for(int k=i+; k<n; k++)
{
if(pos->next[k]->cnt) continue;
int t=pos->next[k]-pool;
dp[k][t]=min(dp[k][t],dp[i][j]+dist(P[i],P[k]));
}
}
}
double ans=inf;
for(int i=; i<cnt; i++) ans=min(ans,dp[n-][i]);
if(ans==inf) printf("Can not be reached!\n");
else printf("%.2lf\n",ans);
}
}
}
11848330 | 2014-10-11 14:48:53 | Accepted | 4511 | 109MS | 748K | 2865B | C++ | Physcal |
HDU 4511 (AC自动机+状态压缩DP)的更多相关文章
- hdu 4057(ac自动机+状态压缩dp)
题意:容易理解... 分析:题目中给的模式串的个数最多为10个,于是想到用状态压缩dp来做,它的状态范围为1-2^9,所以最大为2^10-1,那我们可以用:dp[i][j][k]表示长度为i,在tri ...
- hdu 2825(ac自动机+状态压缩dp)
题意:容易理解... 分析:在做这道题之前我做了hdu 4057,都是同一种类型的题,因为题中给的模式串的个数最多只能为10个,所以我们就很容易想到用状态压缩来做,但是开始的时候我的代码超时了dp时我 ...
- POJ 3691 (AC自动机+状态压缩DP)
题目链接: http://poj.org/problem?id=3691 题目大意:给定N个致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题 ...
- bzoj1195 神奇的ac自动机+状态压缩dp
/* 难的不是ac自动机,是状态压缩dp 之前做了一两题类似题目,感觉理解的还不够透彻 */ #include<iostream> #include<cstdio> #incl ...
- HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )
模板来自notonlysuccess. 模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩. 将模式串加入AC自动机,最多有10*100个状态. dp[i][j][k]:串长为i,在T ...
- HDU 4758 Walk Through Squares( AC自动机 + 状态压缩DP )
题意:给你两个串A,B, 问一个串长为M+N且包含A和B且恰好包含M个R的字符串有多少种组合方式,所有字符串中均只含有字符L和R. dp[i][j][k][S]表示串长为i,有j个R,在自动机中的状态 ...
- 计蒜客-蒜场抽奖(AC自动机+状态压缩DP)
题解:题意不再说了,题目很清楚的. 思路:因为N<=10,所以考虑状态压缩 AC自动机中 val[1<<i]: 表示第i个字符串.AC自动机中fail指针是指当前后缀在其他串里面所能 ...
- hdu 3341(ac自动机+状态压缩)
题意:容易理解... 思路:首先一开始容易想到要用到dp,开设一个dp[41][41][41][41][501]的数组来解决,但是明显内存已经超出范围了,于是就想如何减少内存呢?只要知道A.T.C.G ...
- hdu 2825 aC自动机+状压dp
Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
随机推荐
- django静态文件查找逻辑
最近被django的静态文件配置整疯了. 决定直捣黄龙,看看底层代码: 首先用manage finstatic xxxx.js 看看处理逻辑,发现主要在:C:\Python27\Lib\site-pa ...
- 用nginx做反向代理来访问防外链图片
用nginx做反向代理来访问防外链图片 女儿的博客从新浪搬到wordpress后,发现原来博客上链接的新浪相册的图片都不能访问了,一年的博客内容,一个个去重新上传图片,修正链接也是个大工程.还是得先想 ...
- DP:Ant Counting(POJ 3046)
数蚂蚁 题目大意:一只牛想数蚂蚁,蚂蚁分成很多组,每个组里面有很多只蚂蚁,现在问你有多少种组合方式 (说白了就是问1,1,1,...,2...,3...,4...)这些东西有多少种排列组合方式 这一道 ...
- dt.jar设计时rt.jar运行时
很多人在初学Java的时候,都要配置环境变量.在配置CLASSPATH的时候,都会加上一个当前目录.,还有两个jar:dt.jar和tools.jar.其实好多人都不了解这两个jar的作用,尤其是dt ...
- [火狐REST] 火狐REST 模拟 HTTP get, post请求
- Ubuntu 12.10 安装 jdk-7u10-linux-x64.tar.gz(转载)
在Ubuntu 12.10下安装 jdk-7u10-linux-x64.tar.gz 总的原则:将jdk-7u10-linux-x64.tar.gz压缩包解压至/usr/lib/jdk,设置jdk环境 ...
- 配置SecureCRT连接本地虚拟机中的Linux系统
转自:http://www.pythoner.com/196.html 由于平时公司开发时都是使用SecureCRT连接的Linux服务器,所以也想使用SecureCRT在自己电脑上连接本地虚拟机中的 ...
- windows 常用快捷键
快捷键,学会就可以扔掉鼠标. F1帮助 F2改名 F3搜索 F4地址 F5刷新 ...
- 何时使用hadoop fs、hadoop dfs与hdfs dfs命令(转)
hadoop fs:使用面最广,可以操作任何文件系统. hadoop dfs与hdfs dfs:只能操作HDFS文件系统相关(包括与Local FS间的操作),前者已经Deprecated,一般使用后 ...
- mysql导入出现MySQL Error 1153 - Got a packet bigger than 'max_allowed_packet' bytes
解决办法: 就搞定了.