您的位置:首页 > 大数据 > 人工智能

【动态规划】[POJ 1229]Wild Domains

2015-07-13 13:56 525 查看
其实就是把每一部分的内容缩成一个点,然后把每一个特殊意义的符号用方便表示的符号表示出来

比如

(@表示必须选一个, #表示选择1个或者不选,的含义和*一样)
! -> @@# * ->的含义和*一样)
! -> @@# * -> ? -> @##

然后

[code]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就好了f(i,j)f(i,j)表示第一个的前i个和第二个的前j个是否可以被匹配

[code]#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: