某高中oj b179: 空罐 Cans
来源:互联网 发布:装修淘宝店用什么软件 编辑:程序博客网 时间:2024/06/02 23:23
题目链接:http://zerojudge.tw/ShowProblem?problemid=b179
题目大意:一个基因可以分裂出四个子基因,这四个基因末尾增加a,b,c,或d,但本身的第一个碱基会失去,当基因长度为0时会死去,同时当基因含有制病片段时就会生病,问p天后有好多死去,好多生病。
题目思路:ac自动机dp,dp[i][j][k]表示第i天在结点k有多少长度为j的基因。对于基因变短,可以由fail指针转移。要分两种
情况讨论,长度小于结点深度和不小于结点深度。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<string>#include<queue>#include<algorithm>#include<vector>#include<stack>#include<list>#include<iostream>#include<map>using namespace std;#define inf 0x3f3f3f3f#define Max 110#define mod 10007int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}struct node{ int cnt,fail,dep; int next[4]; void init() { cnt=fail=dep=0; memset(next,0,sizeof(next)); }}tri[1600];char s[1000],str[1000];int dp[330][110][1600],q[1600];int cnt;void insert(char *s){ int i,p,x; p=0; for(i=0;s[i];i++) { x=s[i]-'a'; if(!tri[p].next[x]) { tri[++cnt].init(); tri[cnt].dep=tri[p].dep+1; tri[p].next[x]=cnt; } p=tri[p].next[x]; } tri[p].cnt++;}void bfs(){ int i,p,head,tail,suf; p=head=tail=0; for(i=0;i<4;i++) { if(tri[0].next[i]) { q[tail++]=tri[0].next[i]; tri[q[tail-1]].fail=0; } } while(head<tail) { p=q[head++],suf=tri[p].fail; tri[p].cnt+=tri[suf].cnt; for(i=0;i<4;i++) { if(tri[p].next[i]) { q[tail++]=tri[p].next[i]; tri[q[tail-1]].fail=tri[suf].next[i]; } else tri[p].next[i]=tri[suf].next[i]; } }}void solve(char *s,int n){ int i,j,k,g,p,x,pos; int len=strlen(s); p=0; for(i=0;i<=n;i++) for(j=0;j<=100&&j<=n+len;j++) for(k=0;k<=cnt;k++) dp[i][j][k]=0; for(i=0;s[i];i++) { x=s[i]-'a'; p=tri[p].next[x]; if(tri[p].cnt) { printf("0 1\n"); return; } } dp[0][len][p]=1; for(i=0;i<n;i++) for(j=1;j<=100&&j<=n+len;j++) for(k=0;k<=cnt;k++) { if(dp[i][j][k]==0||tri[k].cnt) continue; for(g=0;g<4;g++) { pos=tri[k].next[g]; dp[i+1][j+1][pos]+=dp[i][j][k]; dp[i+1][j+1][pos]%=mod; } if(j-1<tri[k].dep) { pos=tri[k].fail; dp[i+1][j-1][pos]+=dp[i][j][k]; dp[i+1][j-1][pos]%=mod; } else { dp[i+1][j-1][k]+=dp[i][j][k]; dp[i+1][j-1][k]%=mod; } } int ans1=0,ans2=0; for(i=1;i<=n;i++) ans1=(ans1+dp[i][0][0])%mod; for(i=1;i<=n;i++) for(j=0;j<=100&&j<=n+len;j++) for(k=0;k<=cnt;k++) { // printf("i %d j %d k %d dp %d\n",i,j,k,dp[i][j][k]); if(tri[k].cnt) ans2=(ans2+dp[i][j][k])%mod; } printf("%d %d\n",ans1,ans2);}int main(){ int p,n,i,j; while(scanf("%s",s)!=EOF) { scanf("%d%d",&p,&n); cnt=0; tri[0].init(); while(n--) { scanf("%s",str); insert(str); } bfs(); solve(s,p); }}
- 某高中oj b179: 空罐 Cans
- b179: 空罐 Cans
- ZeroJudge-b179 空罐 Cans 可爱的AC自动机DP..
- b179 cans
- zerojudge 空罐 Cans
- 空罐Cans
- 空罐Cans (ac自动机 dp)
- 高中OJ 3792. 【NOIP2014模拟8.20】分队问题
- 高中OJ 3793. 【NOIP2014模拟8.20】数字对
- 高中OJ 3794. 【NOIP2014模拟8.20】高级打字机
- oj-11-C-画空三角形
- [杂记]某高中对口高考培训班授课有感
- 高中同学会
- 华容高中
- 高中单词
- 高中五開發菜鳥初來報到
- 高中 诗
- 高中 文
- 一般的函数指针和类的函数指针
- Objective-C语法之代码块(block)的使用
- 游戏开发新的
- 运行bat隐藏cmd窗口
- C++ Boost 库文档索引
- 某高中oj b179: 空罐 Cans
- C常用函数理解与识记 第二季
- mre下的控件实现(一、公共的宏定义)
- USCAO section Mother's Milk(搜索)
- Android创建启动画面
- x window简介
- struts2 井号,星号,百分号
- abap 单元格级别的操作ALV.
- SQL优化-索引(1)