hdu 6170 dp

题意:

给出两个字符串,第一个字符串只包含小写或者大写字母,第二个字符串包含小写或者大写字母或者特殊字符“.”和“*”,这里“.”可以替换为任意字符,但是不能变成空。

这里“a*”可以变成空串,可以变成a,也可以是aa,也可以是aaa,还可以是aaaa.以此类推,不限长度。

问第二个串和第一个串是否能够完全相等。

题解:

题目给的数据是比较小的,贪心的话数据太小了,直接模拟的话由于”*“的个数可以存在多个 ,有个动态的过程,所以考虑用dp。

对于两个字符串的dp接触过一些,最经典的就是公共子序列的问题,这里定义dp[i][j]为s[0]~s[i]与t[0]~t[j]的匹配情况,0表示不匹配,1表示匹配。

关于状态转移方程,比较难处理的还是‘*’的情况。具体解释看代码:

ac代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
int dp[2501][2501];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        char s[2510],t[2510];
        scanf("%s",s+1);// 给空串留一个位置
        scanf("%s",t+1);
        memset(dp,0,sizeof(dp));
        dp[0][0]=1; // 空串当然为1
       // cout<<s<<' '<<t<<endl;
        int slen=strlen(s+1);
        int tlen=strlen(t+1);
       // cout<<slen<<' '<<tlen<<endl;
        for(int i=1;i<=slen;i++)
        {
            for(int j=1;j<=tlen;j++)
            {
                if(j==2 && t[j]=='*') dp[0][j]=1; // 特殊情况要注意一下  给个样例 a  b*a*  输出yes
                if(t[j]=='.') dp[i][j]=dp[i-1][j-1];
                else if(t[j]!='*')
                {
                    if(s[i]==t[j]) dp[i][j]=dp[i-1][j-1];
                }
                else
                {
                    dp[i][j]=max(dp[i][j-1],dp[i][j-2]);// dp[i][j-1]为a*表示为a的情况 dp[i][j-2]为a*表示为空的情况·
                    if(dp[i-1][j] && s[i-1]==s[i]) dp[i][j]=1;// 这里表示a*为2个a以上的情况
                }
            }
        }
        if(dp[slen][tlen]) cout<<"yes"<<endl;
        else cout<<"no"<<endl;
    }
    return 0;
}

 

posted @ 2017-08-23 11:12  猪突猛进!!!  阅读(252)  评论(0编辑  收藏  举报