1. 程式人生 > >hdu6170 Two strings (DP)

hdu6170 Two strings (DP)

 

Problem Description

Giving two strings and you should judge if they are matched.
The first string contains lowercase letters and uppercase letters.
The second string contains lowercase letters, uppercase letters, and special symbols: “.” and “*”.
. can match any letter, and * means the front character can appear any times. For example, “a.b” can match “acb” or “abb”, “a*” can match “a”, “aa” and even empty string. ( “*” will not appear in the front of the string, and there will not be two consecutive “*”.

 

 

Input

The first line contains an integer T implying the number of test cases. (T≤15)
For each test case, there are two lines implying the two strings (The length of the two strings is less than 2500).

 

 

Output

For each test case, print “yes” if the two strings are matched, otherwise print “no”.

 

 

Sample Input

 

3 aa a* abb a.* abb aab

 

 

Sample Output

 

yes yes no

 

題意:題意:第一段是隻有字母的字串,第二段是有字母以及特殊字元的字串,'.'可以代替任意字元,'*'可以使它前一位的字元出現任意次數,甚至是0次(0次就代表著刪掉*前面那個字元嘛),問兩串字串是否匹配。

 

思路:我們假設s1是先輸入的字串,s2是後輸入的字元,dp[i][j] 表示s2的前i個元素和s1的前j個元素的匹配情況,匹配則1,不匹配則0;定好規矩之後,我們就開始討論各種情況

(1)當s2[i]='.'或者等於與s1[j]匹配的字元,這時肯定是匹配的,所以 dp[i][j]=dp[i-1][j-1];

(2)當s2[i]為'*',比較複雜,咱們先一個個看

    a.如果i是在第二位,單獨將dp[2][0]置1;因為此時若把*前面的元素刪除,就和dp[0][0]一樣了嘛

    b.如果第i-2個元素和s1中的第j個元素匹配。那麼可以把*和它前面的元素刪除,字串也就匹配了。如:a - ab*

    c.如果第i-1個元素和s1中的第j個元素匹配,那麼就只保留*前面的元素,也就是隻刪除了*,也匹配。如:ab-ab*

    d.如果第i個元素和第j-1個元素匹配,且s1[j]==s1[j-1],這時候需要將*賦值成它前面的元素,也匹配如:abb-ab*

     注意:這裡為什麼不是第i-1個和第j-1個呢,因為第i-1個就不是*了,所以肯定會產生不匹配的情況,如accc-ac*,答案應該是yes,但是如果改成i-1和j-1.,就會識別為no

 

AC程式碼:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
 
using namespace std;
 
const int maxs=2500;
 
int dp[maxs+10][maxs+10];
 
int main()
{
    int t;
    char s1[maxs+10],s2[maxs+10];
    int i,j,l1,l2;
 
    scanf("%d",&t);
    while(t--){
		memset(dp,0,sizeof(dp));
		scanf("%s",s1+1);
		scanf("%s",s2+1);
		l1=strlen(s1+1);
		l2=strlen(s2+1);
		dp[0][0]=1;
		if(s2[2]=='*') dp[2][0]=1;	  //!!
		for(j=1;j<=l2;++j){

			for(i=1;i<=l1;++i){
				if(s1[i]==s2[j]||s2[j]=='.'){
					dp[j][i]=max(dp[j][i],dp[j-1][i-1]);
				}
				else if(s2[j]=='*'){
					dp[j][i]=dp[j-1][i]		
							 ||dp[j][i-1]&&s1[i]==s1[i-1]	   
							
							 ||dp[j-2][i];	   
				}
			}
		}
		if(dp[l2][l1]) printf("yes\n");
		else printf("no\n");
    }
 
    return 0;
}