【动态规划】[POJ 1229]Wild Domains
其实就是把每一部分的内容缩成一个点,然后把每一个特殊意义的符号用方便表示的符号表示出来
比如
(@表示必须选一个, #表示选择1个或者不选,的含义和*一样)
! -> @@# * -> ? -> @##
然后
if(check(str[0][i][0]) || check(str[1][j][0])){
if(str[0][i][0] == '@') f[i][j] = f[i][j] || f[i-1][j-1];
if(str[0][i][0] == '#') f[i][j] = f[i][j] || f[i-1][j-1] || f[i-1][j];
if(str[0][i][0] == '$') f[i][j] = f[i][j] || f[i-1][j-1] || f[i][j-1];
if(str[1][j][0] == '@') f[i][j] = f[i][j] || f[i-1][j-1];
if(str[1][j][0] == '#') f[i][j] = f[i][j] || f[i-1][j-1] || f[i][j-1];
if(str[1][j][0] == '$') f[i][j] = f[i][j] || f[i-1][j-1] || f[i-1][j];
}else{
if(strcmp(str[0][i], str[1][j]) == 0) f[i][j] = f[i-1][j-1];
else f[i][j] = false;
}
搞一下DP就好了
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 1000;
bool f[MAXN+10][MAXN+10];
char s[3][20]={"@##", "@@$", "$"};
char tmp[MAXN+10], str[2][MAXN+10][MAXN+10];
int l1, l2;
bool check2(char c){
return c == '.' || c == '!' || c == '?' || c == '*';
}
int solve(int num){
scanf("%s", tmp+1);
int len = strlen(tmp+1), len2=0;
memset(str[num], 0, sizeof str[num]);
for(int i=1;i<=len;i++){
if(tmp[i] == '?'){
str[num][++len2][0] = s[0][0];
str[num][++len2][0] = s[0][1];
str[num][++len2][0] = s[0][2];
}
else if(tmp[i] == '!'){
str[num][++len2][0] = s[1][0];
str[num][++len2][0] = s[1][1];
str[num][++len2][0] = s[1][2];
}
else if(tmp[i] == '*'){
str[num][++len2][0] = s[2][0];
}
else if(tmp[i] != '.'){
int j=0; ++len2;
while(i+j<=len&&!check2(tmp[i+j])){
str[num][len2][j] = tmp[i+j];
j++;
}
if(i+j > len) return len2;
i = i+j-1;
}
}
return len2;
}
inline bool check(char t){return t=='@'||t=='#'||t=='$';}
void work(){
f[0][0] = true;
for(int i=1;i<=l1;i++)
for(int j=1;j<=l2;j++){
if(check(str[0][i][0]) || check(str[1][j][0])){
if(str[0][i][0] == '@') f[i][j] = f[i][j] || f[i-1][j-1];
if(str[0][i][0] == '#') f[i][j] = f[i][j] || f[i-1][j-1] || f[i-1][j];
if(str[0][i][0] == '$') f[i][j] = f[i][j] || f[i-1][j-1] || f[i][j-1];
if(str[1][j][0] == '@') f[i][j] = f[i][j] || f[i-1][j-1];
if(str[1][j][0] == '#') f[i][j] = f[i][j] || f[i-1][j-1] || f[i][j-1];
if(str[1][j][0] == '$') f[i][j] = f[i][j] || f[i-1][j-1] || f[i-1][j];
}else{
if(strcmp(str[0][i], str[1][j]) == 0) f[i][j] = f[i-1][j-1];
else f[i][j] = false;
}
}
}
int main(){
int n;
scanf("%d", &n);
for(int i=1;i<=n;i++){
memset(f, 0, sizeof f);
l1 = solve(0); l2 = solve(1);
work();
printf("%s\n", f[l1][l2]?"YES":"NO");
}
return 0;
}