HDOJ-3427 & ZOJ-3190 Resource Archiver AC自动机压缩状态DP..
来源:互联网 发布:usb网络打印服务器设置 编辑:程序博客网 时间:2024/05/16 16:12
先用resources和virus构造出AC自动机..
本题最暴力的状态是很好想到的...dp[a][b][c]...代表a长度时某串后缀能到AC自动机点b..能得到c些resources..其中c是一个用十进制表示的二进制数..代表题目里最多10个resources的存在情况...可见此种dp..状态最多可为10000*60000*1024...爆空间爆时间..各种爆..爆得体无完肤!!..
根据sha崽的提示..本题AC自动机里虽然点很多..但实际在更新转移中存在意义的点只有包含了resources的后缀点..而这些点的个数只有不超过50个..so..将这些后缀点之间的最短路径算出来...我就是直接枚举每个点BFS的...然后直接对这些存在转移意义的后缀点DP..瞬间时间和空间爆降阿..
正如HDOJ本题Dicuss里有人说的..本题数据还是很弱的..我找了好多网上发布的AC代码...没有一个代码能够跑出完全正确的结果..错得最多的是Discuss里的:
3 3
0001
0000
10000
010
101
111
好不容易找到这个数据能过的..结果又一大堆没考虑resources相同的..还有一些连手算的简单数据都出错..这道题数据的不严谨.众AC代码漏洞百出.真是奇葩.
我WA了十多次的原因是因为..白痴了..一个赋初值的地方没注意到要清0..结果..WA得想吐..
Program:
#include<iostream>#include<stdio.h>#include<string.h>#include<math.h>#include<queue>#define oo 2000000000#define ll long longusing namespace std; struct node{ int son[2],fail,d,n; bool w;}point[60005];int n,m,_2jie[12],dis[55][55],dp[55][1026],useful[55];char s[50005];queue<int> myqueue;int used[60005];int main(){ int len,i,j,x,h,k,num,ans,goal; _2jie[0]=1; for (i=1;i<=10;i++) _2jie[i]=_2jie[i-1]*2; while (~scanf("%d%d",&n,&m)) { if (!n && !m) break; memset(point,0,sizeof(point)); num=0; for (j=0;j<n;j++) { scanf("%s",s); len=strlen(s); h=0; for (i=0;i<len;i++) { if (!point[h].son[s[i]-'0']) point[h].son[s[i]-'0']=++num; h=point[h].son[s[i]-'0']; } point[h].d+=_2jie[j]; } while (m--) { scanf("%s",s); len=strlen(s); h=0; for (i=0;i<len;i++) { if (!point[h].son[s[i]-'0']) point[h].son[s[i]-'0']=++num; h=point[h].son[s[i]-'0']; if (point[h].w) break; } point[h].w=true; } while (!myqueue.empty()) myqueue.pop(); for (i=0;i<2;i++) if (point[0].son[i]) myqueue.push(point[0].son[i]); num=1; point[0].n=1; useful[1]=0; while (!myqueue.empty()) { h=myqueue.front(); myqueue.pop(); if (point[point[h].fail].w) point[h].w=true; if (point[h].w) continue; point[h].d|=point[point[h].fail].d; if (point[h].d) { point[h].n=++num; useful[num]=h; } for (i=0;i<2;i++) { k=point[h].fail; while (k && !point[k].son[i]) k=point[k].fail; point[point[h].son[i]].fail=point[k].son[i]; if (!point[h].son[i]) point[h].son[i]=point[k].son[i]; else myqueue.push(point[h].son[i]); } } memset(dis,0,sizeof(dis)); for (i=1;i<=num;i++) { memset(used,0,sizeof(used)); myqueue.push(useful[i]); used[useful[i]]=1; while (!myqueue.empty()) { h=myqueue.front(); myqueue.pop(); if (point[h].w) continue; if (point[h].n) dis[i][point[h].n]=used[h]-1; for (j=0;j<2;j++) if (!used[point[h].son[j]]) { used[point[h].son[j]]=used[h]+1; myqueue.push(point[h].son[j]); } } } goal=_2jie[n]-1; memset(dp,0,sizeof(dp)); dp[1][0]=1; while (n--) { for (i=1;i<=num;i++) for (k=0;k<goal;k++) if (dp[i][k]) for (j=1;j<=num;j++) if (dis[i][j]) { x=k|point[useful[j]].d; if (!dp[j][x] || dp[j][x]>dp[i][k]+dis[i][j]) dp[j][x]=dp[i][k]+dis[i][j]; } } ans=oo; for (i=1;i<=num;i++) if (dp[i][goal] && dp[i][goal]<ans) ans=dp[i][goal]; printf("%d\n",ans-1); } return 0;}
- HDOJ-3427 & ZOJ-3190 Resource Archiver AC自动机压缩状态DP..
- hdu3247 Resource Archiver AC自动机+状态压缩DP
- 【ZOJ】 3190 Resource Archiver AC自动机+BFS预处理+DP
- HDU 3247 Resource Archiver (AC自动机 + BFS + 状态压缩DP)
- HDU 3247 Resource Archiver(AC自动机+BFS+状态DP)
- HDU 3247 Resource Archiver(AC自动机+BFS+状态DP)
- 【AC自动机】 HDOJ 3247 Resource Archiver
- HDU3247 Resource Archiver(AC自动机+DP)
- hdu3341 Resource Archiver AC自动机+DP
- hdu 3247 Resource Archiver(AC自动机+状压DP)
- [AC自动机+spfa+状压dp] hdu 3247 Resource Archiver
- hdu 3247 Resource Archiver(AC自动机+BFS+DP)
- hdu 3247 Resource Archiver (ac自动机+BFS+状压dp)
- HDU 3247 Resource Archiver[AC自动机+最短路+dp]
- HDU 3247-Resource Archiver(AC自动机+BFS+DP)
- zoj 3545 AC自动机+状态dp
- HDU 3247 AC自动机 + 状态压缩dp
- HDU 4534(ac自动机+状态压缩dp)
- 进制转换
- Mysql中文乱码
- Android下使用TelephonyManager类获取设备电话相关信息
- MyEclipse优化启动 去除不需要加载的模块 关掉没用的启动项
- oracle修改 11g processes参数导致:无法启动解决方法 shared memory realm does not exists
- HDOJ-3427 & ZOJ-3190 Resource Archiver AC自动机压缩状态DP..
- 高速单行道 IN Name Id”:道路入口有一辆车请求进入
- 解决android网络异常java.net.SocketException: Bad address family
- PC电脑和Android模拟器访问及模拟器之间tcp/udp通信
- Android2.2及2.3版本调用前置摄像头
- IP地址与整数之间的转换
- M2eclipse使用Maven编译Android下i-jetty
- android实现TextView垂直或水平滚动
- android自定义View-垂直滚动的TextView