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; }