poj 1229 字符串模糊匹配dp
之前虽然两过一段时间的dp,但是还是没有接触过这样的模糊匹配的状态转移,所以说状态转移是永远都学不完的东西啊。。。
其实之所以能够写出这样一道题,还是看了这位大哥的博客http://www.cnblogs.com/staginner/archive/2012/01/25/2329379.html
里面讲得比较全面吧,。。。
把通配符的意义改变一下,那么这样状态就能得到很好的记录。
引用那位大哥里面的话,那就是重新定义一下通配符的意义
*:含义不变,至少配一个,多则不限。
?:只能配一个。
!:可以配一个,也可以什么都不配。
这样我们就得到了一个新旧通配符的转换公式:*->*, ?-> ?!!,!-> ??*。
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<stdlib.h> 5 #define N 600 6 char str[N],A[N][N],B[N][N]; 7 int headA,headB,dp[N][N]; 8 void init() 9 { 10 scanf("%s",str); 11 int i=0,j; 12 headA=headB=1; 13 while(str[i]) 14 { 15 for(j=0;str[i]&&str[i]!='.';j++,i++) 16 A[headA][j]=str[i]; 17 A[headA][j]='\0'; 18 headA++; 19 if(A[headA-1][0]=='?') 20 { 21 A[headA++][0]='!'; 22 A[headA++][0]='!'; 23 } 24 else 25 if(A[headA-1][0]=='!') 26 { 27 A[headA-1][0]='?'; 28 A[headA++][0]='?'; 29 A[headA++][0]='*'; 30 } 31 if(!str[i])break; 32 i++; 33 } 34 scanf("%s",str); 35 i=0; 36 while(str[i]) 37 { 38 for(j=0;str[i]&&str[i]!='.';j++,i++) 39 B[headB][j]=str[i]; 40 B[headB][j]='\0'; 41 headB++; 42 if(B[headB-1][0]=='?') 43 { 44 B[headB++][0]='!'; 45 B[headB++][0]='!'; 46 } 47 else 48 if(B[headB-1][0]=='!') 49 { 50 B[headB-1][0]='?'; 51 B[headB++][0]='?'; 52 B[headB++][0]='*'; 53 } 54 if(!str[i])break; 55 i++; 56 } 57 } 58 void solution() 59 { 60 memset(dp,0,sizeof(dp)); 61 dp[0][0]=1; 62 for(int i=1;i<headA;i++) 63 { 64 for(int j=1;j<headB;j++) 65 { 66 if(A[i][0]=='*'||A[i][0]=='?'||A[i][0]=='!'||B[j][0]=='*'||B[j][0]=='?'||B[j][0]=='!') 67 { 68 if(A[i][0]=='*') 69 dp[i][j]=(dp[i][j]||dp[i][j-1]||dp[i-1][j-1]); 70 if(A[i][0]=='?') 71 dp[i][j]=(dp[i][j]||dp[i-1][j-1]); 72 if(A[i][0]=='!') 73 dp[i][j]=(dp[i][j]||dp[i-1][j]||dp[i-1][j-1]); 74 if(B[j][0]=='*') 75 dp[i][j]=(dp[i][j]||dp[i-1][j-1]||dp[i-1][j]); 76 if(B[j][0]=='?') 77 dp[i][j]=(dp[i][j]||dp[i-1][j-1]); 78 if(B[j][0]=='!') 79 dp[i][j]=(dp[i][j]||dp[i][j-1]||dp[i-1][j-1]); 80 } 81 else 82 { 83 if(strcmp(A[i],B[j])==0) 84 dp[i][j]=dp[i-1][j-1]; 85 else 86 dp[i][j]=0; 87 } 88 } 89 } 90 if(dp[headA-1][headB-1]) 91 printf("YES\n"); 92 else 93 printf("NO\n"); 94 } 95 int main() 96 { 97 int t; 98 scanf("%d",&t); 99 while(t--) 100 { 101 init(); 102 solution(); 103 } 104 return 0; 105 }