hdu4758 Walk Through Squares AC自动机(trie图)DP
来源:互联网 发布:最新金山画王软件 编辑:程序博客网 时间:2024/06/12 05:21
提议大致是给n,m,再给两个非空的不相同的只包含R或D字符串s1,s2,问用n个R,m个D可以组成多少种包含s1,s2的字符串。大致思路的话,先根据两个字符串构造trie图,其实就是把失配函数优化掉的ac自动机。之后用dp[i][x][y][k]表示在自动机上状态i,用x个R,y个D,包含s1,s2的状态.令初值dp[0][0][0][0]=1,向上DP,最后统计dp[i][n][m][3](0<=i<top)的和即可。
#include <iostream>#include <algorithm>#include <cstdio>#include <memory.h>#include <string>#include <cstring>#include <queue>using namespace std;typedef long long ll;const int maxn=420;const int tk=2;int tree[maxn][tk];int val[maxn];int last[maxn];int f[maxn];int n,m,p,q,k;int top;int dp[220][110][110][4];int ok[maxn];const int mod=1000000007;inline int idx(char s){ if (s=='R') return 0; return 1;}struct autoAC{ void init() { top=1; tree[0][0]=tree[0][1]=0; memset(val,0,sizeof val); memset(f,0,sizeof f); memset(last,0,sizeof last); } void insert(char* s,int rank) { int rt,nxt; for (rt=0; *s; rt=nxt,++s) { nxt=tree[rt][idx(*s)]; if (nxt==0) { tree[rt][idx(*s)]=nxt=top; tree[top][0]=tree[top][1]=0; top++; } } val[rt]=rank; } void getFail() { queue<int> q; f[0]=0; for (int c=0; c<tk; c++) { int u=tree[0][c]; if (u) { q.push(u); f[u]=0; last[u]=0; } } while(!q.empty()) { int r=q.front(); q.pop(); for (int c=0; c<tk; c++) { int u=tree[r][c]; if (!u) { tree[r][c]=tree[f[r]][c]; continue; } q.push(u); int v=f[r]; while(v && !tree[v][c]) v=f[v]; f[u]=tree[v][c]; last[u]=val[f[u]]? f[u] : last[f[u]]; } } }}ac;int tt;int mx,my;char s[105],ss[105],str[105];inline void work(){ memset(ok,0,sizeof ok); for (int i=0; i<top; i++) { int j=last[i]; ok[i]=val[i]; while(j) { ok[i]=ok[i]|val[j]; j=last[j]; } } dp[0][0][0][0]=1; int sta; for (int x=0; x<=mx; x++) for (int y=0; y<=my; y++) for (int i=0; i<top; i++) for (int k=0; k<4; k++) { if (dp[i][x][y][k]==0) continue; if (x<mx) { int nxt=tree[i][0]; sta=k|ok[nxt]; dp[nxt][x+1][y][sta]+=dp[i][x][y][k]; if (dp[nxt][x+1][y][sta]>=mod) dp[nxt][x+1][y][sta]-=mod; } if (y<my) { int nxt=tree[i][1]; sta=k|ok[nxt]; dp[nxt][x][y+1][sta]+=dp[i][x][y][k]; if (dp[nxt][x][y+1][sta]>=mod) dp[nxt][x][y+1][sta]-=mod; } } ll res=0; for (int i=0; i<top; i++) { res+=dp[i][mx][my][3];// if (res>=mod) res-=mod; } res%=mod; cout<<res<<endl;}int main(){// freopen("in.txt","r",stdin); scanf("%d",&tt); while(tt--) { ac.init(); scanf("%d%d",&mx,&my); for (int i=1; i<=2; i++) { scanf("%s",s); ac.insert(s,i); } ac.getFail(); memset(dp,0,sizeof dp); work(); } return 0;}
- hdu4758 Walk Through Squares AC自动机(trie图)DP
- hdu4758 Walk Through Squares (AC自动机+DP)
- hdu4758---Walk Through Squares(AC自动机+dp)
- HDU4758 Walk Through Squares(AC自动机+状压DP)
- HDU 4758-Walk Through Squares(AC自动机+状压DP)
- HDU 4758 Walk Through Squares (AC自动机 + 状压dp)
- HDU4758-Walk Through Squares
- hdu 4758 Walk Through Squares(AC自动机+DP,4级)
- HDU 4758 Walk Through Squares && AC自动机+状压DP
- HDU - 4758 Walk Through Squares (AC自动机+DP)
- hdu 4758 - Walk Through Squares(AC自动机+DP)现场赛
- hdu 4758 Walk Through Squares AC自动机
- hdu 4758 Walk Through Squares(自动机+DP)
- HDU 4758 Walk Through Squares(自动机+DP)
- hdu4758 AC自动机+dp
- HDU4758 AC自动机+DP (HDU4758与HDU2222)
- hdu4758(ac自动机,状态压缩dp)
- hdu4758Walk Through Squares【AC自动机+dp】
- poj1961 Period (KMP)
- 从一道面试题分析Linux进程+IO缓冲区机制
- 对象和集合初始值设定项
- java 句子中得单词顺序倒过来
- lua结合cocosbuilder开发游戏-不再勾选js controller了
- hdu4758 Walk Through Squares AC自动机(trie图)DP
- CPPUNIT在vs2010实践的编译配置实践
- Esper学习之七:EPL语法(三)
- Linux内核的变频机制
- SQL查询案例---两表关联更新使用VIEW
- Harris角点检测
- [每日一题] 11gOCP 1z0-053 :2013-10-1 persistent lightweight jobs...........................11
- 数据库事务
- dataTable 插件的应用