HDU 2457 ac机+DP(基础DP)
来源:互联网 发布:大数据时代 企业管理 编辑:程序博客网 时间:2024/05/19 07:10
http://acm.split.hdu.edu.cn/showproblem.php?pid=2457
大体思路就是说 :
对给定的字符串(病毒串)构造AC机,标记每个病毒串的末尾,并在构造fail指针时 如果当前节点的失败指针是病毒串那么当前节点也作为标记。 因为 AC机的状态转移会使得当前节点转移到失败指针所指向的节点中来。
之后把给你的串(匹配串)进行DP,假设DP初始值最大 MME(dp,inf) ,并设dp[0][0]=0;那么dp[i][j] 表示为 长为 i 的串如果走到了第 j 个状态那么有多少种方法。那么每次遇到病毒串要跳过,每个状态为INF时也要跳过,表明到达当前这个长度的第j个状态之前没有经历过 因为只有一个串,那么他所经过的状态一定是一样的。
之后到达 j 状态后枚举每个子节点,同样跳过所有病毒串,那么当增加了一个长度之后到达了另一个新状态后所得到的dp[i+1][当前j状态的某个儿子的状态] 就为 min(dp[i+1][[当前j状态的某个儿子的状态],dp[i][j](去掉当前节点之后判断当前节点是否需要改变,如果当前节点与你j状态此时的儿子一样不需要改变,如不一样则需要改变一次,那么dp[i][j]+1;
#include <stdio.h>#include <string.h>#include <iostream>#include <queue>#define maxs 1050#define MME(i,j) memset(i,j,sizeof(i))#define inf 0x3f3f3f3fusing namespace std;int id['Z'+1];char s[maxs];int dp[maxs][maxs];void setid(){ id['A']=0; id['G']=1; id['C']=2; id['T']=3;}struct node{ int nexts[maxs][4],fail[maxs],ends[maxs]; int root,L; int newnode() { for(int i=0;i<4;i++) nexts[L][i]=-1; ends[L++]=0; return L-1; } // Rt void init() { L=0; root=newnode();MME(fail,0); MME(ends,0);} void Insert(char *s) { int len=strlen(s),idex,now=root; for(int i=0;i<len;i++) { idex=id[s[i]]; if(nexts[now][idex]==-1) nexts[now][idex]=newnode(); now=nexts[now][idex]; } ends[now]=1;// 标记该点为 疾病 DNA } void build() { queue<int>Q; fail[root]=root; for(int i=0;i<4;i++) { if(nexts[root][i]==-1) nexts[root][i]=root; else{ fail[nexts[root][i]]=root; Q.push(nexts[root][i]); } } int now; while(!Q.empty()) { now=Q.front(); if(ends[ fail[ now ] ]) ends[ now ]=1; Q.pop(); for(int i=0;i<4;i++) { if( nexts[now][i]==-1 ) nexts[now][i] = nexts[fail[now]][i]; else { fail[ nexts[now][i] ] =nexts[fail[now]][i]; Q.push(nexts[now][i]); } } } } int DP(char *s) { MME(dp,inf); // printf("%d\n",dp[1][1]); dp[0][0]=0; int len=strlen(s); for( int i=0;i<len;i++ ) { for( int j=0;j<L;j++ ) { if( ends[j] ) continue; if(dp[i][j]==inf ) continue; for(int ch=0;ch<4;ch++) { int &temp=nexts[j][ch]; if( ends[temp] ) continue; dp[i+1][temp] = min(dp[i+1][temp],dp[i][j] + (id[s[i]]!=ch) ); } } } int ans=inf; for(int i=0; i<L; i++) { ans=min(ans,dp[len][i]); } return ans == inf?-1:ans; }}AC;int main(){ int n,cas=1; setid(); while(~scanf("%d",&n) && n) { AC.init(); for(int i=0;i<n;i++) { scanf("%s",s); AC.Insert(s); } AC.build(); // puts("*/*/*/"); scanf("%s",s); int ans=AC.DP(s); //puts("**************"); printf("Case %d: %d\n", cas ++, ans ); } return 0;}
0 0
- HDU 2457 ac机+DP(基础DP)
- hdu 2457(AC自动机+DP)
- hdu 2457 ac自动机dp
- hdu 2457(ac自动机+dp)
- HDU 2457 (AC自动机 DP)
- HDU 2457 AC自动机+dp
- HDU 2457 DNA repair(AC自动机+DP)
- HDU 2457 DNA repair(AC自动机 + DP 入门)
- 字符串练习题: 【HDU 2457】 DNA repair(AC自动机+DP)
- HDU 2457 DNA repair (AC自动机 + DP)
- HDU 2457-DNA repair(AC自动机+DP)
- HDU 2457 || POJ 3691 DNA repair (AC自动机 + dp)
- hdu 2457 DNA repair(AC自动机+DP)
- hdu 2457 ac自动机+简单dp
- HDU 2457 DNA repair(AC自动机+DP)
- 【HDU】2457 DNA repair AC自动机+DP
- hdu 2457 DNA repair ac自动机+dp
- Hdu 2457 DNA repair (ac自动机+dp)
- 性能测试的一些积累
- 学完数字电子电路基础后对计算机的理解
- Android四大组件之:Activity
- CCF-201512-1-数位之和
- Ubuntu14.04下安装ROS Indigo版本
- HDU 2457 ac机+DP(基础DP)
- 获取下一秒时间
- 从用户浏览器输入url到用户看到页面结果的过程,发生了什么事情?
- sublime中如何使用markdown
- keep on coding 8.26^-^
- 递归调用学习笔记
- oracle完全卸载
- 各种导航条
- Python学习笔记之六——函数