1. 程式人生 > >HDU 6170 && 2017 多校訓練:Two strings(DP)

HDU 6170 && 2017 多校訓練:Two strings(DP)


題意:

給你兩個字串:第一個字串只包含小寫大寫字母

第二個字串除了字母之外,還有'.'和'*',其中'.'可以當成任意一個字元,'*'表示前面那個字元可以重複若干次

當然也可以重複0次,例如a.*A可以是aaaA,可以是abbbbA等等,也可以是aA

問兩個串能不能匹配(即第二個字串某種情況下和第一個字串一模一樣)

因為長度只有2500,很好想到DP,dp[x][y]表示第二個字串長度為x,第一個字串長度為y能否完美匹配(1or0)

但是要注意的細節特別多,具體看程式碼

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n, m, dp[2505][2505];
char str[2505], jud[2505];
int main(void)
{
	int T, i, j;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%s%s", str+1, jud+1);
		memset(dp, 0, sizeof(dp));
		n = strlen(str+1);
		m = strlen(jud+1);
		dp[0][0] = 1;
		for(i=1;i<=m;i++)
		{
			if(jud[i]=='*' && i==2)
				dp[i][0] = 1;
			for(j=1;j<=n;j++)
			{
				if(jud[i]=='.')
					dp[i][j] = dp[i-1][j-1];
				else if(jud[i]!='*')
				{
					if(jud[i]==str[j])
						dp[i][j] = dp[i-1][j-1];
				}
				else
				{
					dp[i][j] = max(dp[i-2][j], dp[i-1][j]);
					if((dp[i-1][j-1]==1 || (dp[i][j-1]==1)) && str[j]==str[j-1] && (str[j]==jud[i-1] || jud[i-1]=='.'))
						dp[i][j] = max(dp[i][j], max(dp[i][j-1], dp[i-1][j-1]));
				}
			}
		}
		if(dp[m][n]==1)
			printf("yes\n");
		else
			printf("no\n");
	}
	return 0;
}