比赛 4043级NOIP2022欢乐赛6th 评测结果 AAAAAAAAAAAAAAA
题目名称 基因串 最终得分 100
用户昵称 lihaoze 运行时间 0.856 s
代码语言 C++ 内存使用 1.72 MiB
提交时间 2022-11-18 20:29:28
显示代码纯文本
#include "bits/stdc++.h"

using PCC = std::pair<char, char>;

const int N = 110, INF = 0x3f3f3f3f;
int n, q, f[N][N];
std::map<PCC, std::set<char>> h;

std::set<char> merge[N][N];

std::set<char> unionSet(std::set<char> a, std::set<char> b) {
    std::set<char> ret;
    for (auto i : a) 
        ret.insert(i);
    for (auto i : b)
        ret.insert(i);
    return ret;
}

int main() {
    freopen("gen.in", "r", stdin); 
    freopen("gen.out", "w", stdout);
    
    std::cin >> n;

    for (int i = 1; i <= n; ++ i) {
        std::string s;
        std::cin >> s;
        h[{ s[1], s[2] }].insert(s[0]);
    }

    std::cin >> q;
    while (q --) {
        std::string s;
        std::cin >> s;

        n = s.size();

        memset(f, 0x3f, sizeof f);
        for (int i = 1; i <= n; ++ i) 
            for (int j = 1; j <= n; ++ j) 
                merge[i][j].clear();

        for (int len = 1; len <= n; ++ len) {
            for (int i = 1; i + len - 1 <= n; ++ i) {
                int j = i + len - 1;

                if (i == j) {
                    if (s[i - 1] == 'S') 
                        f[i][j] = 1;
                    merge[i][j].insert(s[i - 1]);
                } else {
                    for (int k = i; k < j; ++ k) {
                        f[i][j] = std::min(f[i][j], f[i][k] + f[k + 1][j]);
                        for (auto a : merge[i][k]) 
                            for (auto b : merge[k + 1][j]) 
                                merge[i][j] = unionSet(merge[i][j], h[{ a, b }]);
                    }
                    if (merge[i][j].count('S')) {
                        f[i][j] = 1;
                    }
                }
            }
        }

        if (f[1][n] < INF) {
            std::cout << f[1][n] << '\n';
        } else {
            std::cout << "NIE" << '\n';
        }
    }
    return 0;
}