Bzoj 2664 [BeiJing wc2012] who hatch

gate

I signed the contract and become a burning horse monkey bars!

This problem kinda funny ...

Interval dp (did not expect it)

The current string is provided Witch s

f [x] [i] [j] indicates character x is restrained in a segment s (i, j)

In the process of dp, since x only 'A' - 'Z'26 species, so here enumerate direct violence.

The rule x restraint or hatch, a total of only 20 species, so it is a direct enumeration.

 

First initialization:

Restraint relationships are 1v1, it is first necessary to be able to exercise restraint which character s [i] handle it.

That is, for x = 'A' - 'Z', check whether restrained x s [i].

As for x can not appear in the Spell ... first do not consider.

Enumeration restraint relationship i, x, x, and if x-> s [i], then f [x] [i] [i] = true

for(int i = 0; i < n; i++)
    for(int x = 0; x < 26; x++)
        for(int t = 0; t < atk[x].size(); t++)
            if(atk[x][t] == s[i])
                F [x] [I] [I] = . 1 ;
 // ATK [x] [t] then x = Y t-th restraint relationship x-> y
The key code (written in front and not the same)

 

Initially only one S, so I want to wipe out the entire Witch, you have to hatch a new one.

A card can only hatch into two, so enumeration breakpoint k ,

Let a, b represents the relationship between a character x hatching the hatched first and second card characters

(I, k) comprised of a restraint, (k + 1, j) b from the restraint,

State transition equation: f [x] [i] [j] = f [a] [i] [k] && f [b] [k + 1] [j]

for(int len = 2; len <= n; len++)
    for(int i = 0; i+len-1 < n; i++) {
        int j = i+len-1;
        for(int x = 0; x < 26; x++)
            for(int t = 0; t < spl[1][x].size(); t++)
                for(int k = i; k <= j; k++)
                    if(f[spl[1][x][t]-'A'][i][k] && f[spl[2][x][t]-'A'][k+1][j])
                        f[x][i][j] = 1;
    }
// SPL [. 1] [x] [t] = Y, SPL [2] [x] [t] = x Z t-th of the incubation relationship x-> yz
The key code (written in front and not the same)

 

Final check f [ 'S'] [1] [len] whether it is true!

 

The complete code is as follows

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
#include<vector>
using namespace std;

int n,m;
int f[30][25][25];
char s[25];
vector <char> atk[30],spl[3][30];

int main () {
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++) {
        scanf("%s",s);
        atk[s[0]-'A'].push_back(s[3]);
    }
    for(int i = 1; i <= m; i++) {
        scanf("%s",s);
        spl[1][s[0]-'A'].push_back(s[3]);
        spl[2][s[0]-'A'].push_back(s[4]);
    }
    while(~scanf("%s",s)) {
        n = strlen(s);
        memset(f,0,sizeof(f));
        for(int i = 0; i < n; i++)
            for(int x = 0; x < 26; x++)
                for(int t = 0; t < atk[x].size(); t++)
                    if(atk[x][t] == s[i])
                        f[x][i][i] = 1;

        for(int len = 2; len <= n; len++)
            for(int i = 0; i+len-1 < n; i++) {
                int j = i+len-1;
                for(int x = 0; x < 26; x++)
                    for(int t = 0; t < spl[1][x].size(); t++)
                        for(int k = i; k <= j; k++)
                            if(f[spl[1][x][t]-'A'][i][k] && f[spl[2][x][t]-'A'][k+1][j])
                                f[x][i][j] = 1;
            }
        if(f['S'-'A'][0][n-1]) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/mogeko/p/11821916.html