nuoyan2010

之前虽然两过一段时间的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 }

 

 

 

分类:

技术点:

相关文章:

  • 2021-11-13
  • 2021-11-28
  • 2021-11-22
  • 2021-11-22
  • 2021-11-13
  • 2021-10-03
  • 2018-10-31
  • 2021-11-13
猜你喜欢
  • 2021-11-22
  • 2021-12-10
  • 2021-11-13
  • 2021-11-22
  • 2021-11-22
  • 2021-11-13
  • 2021-11-13
相关资源
相似解决方案