C. Lazy Narek

https://codeforces.com/contest/2005/problem/C

题意:n个长度为m的字符串,可以任意选取若干个字符串组合起来,然后从中选择narek5个字符拼凑字符串,拼凑成功加5分,如果字母是narek中的其中一个并且没有使用,则扣一分,求最大分数。

思路:dp,维护一个长度为5的数组,依次考虑在当前字符串中以第i个字母为起始字母时,能得到的最大分值。

总结:这里是如何在dp的过程中,保持之前的信息的呢?第一个匹配的字符一定是n,那么dp[0] = 0,后面匹配到了第几个字符,就让第几个字符的下一个代价为0,这样在下一个串中可以接着这个字符进行匹配,当匹配到结尾的时候,在下个串中可以获得的代价就可以+5。

inline void solve(){
    int n, m;
    cin >> n >> m;

    vector<string> a(n);
    for (auto& x : a) {
        cin >> x;
    }

    array<int, 5> dp;
    dp.fill(-INF);
    dp[0] = 0;

    const string target = "narek";

    for (const auto& s : a) {
        auto cur_dp = dp;
        for (int i = 0; i < 5; ++i) {
            int j = i;
            int res = dp[i];
            for (const auto& c : s) {
                if (c == target[j]) {
                    j ++;
                    if (j == 5) {
                        res += 5;
                        j = 0;
                    }
                }
                else if (target.find(c) != target.npos) {
                    res --;
                }
            }
            cur_dp[j] = max(cur_dp[j], res);
        }
        dp = cur_dp;
    }

    int ans = 0;
    for (int i = 0; i < 5; ++i) {
        ans = max(ans, dp[i] - i);
    }

    cout << ans << '\n';
}
posted @ 2024-09-19 09:51  _Yxc  阅读(24)  评论(0编辑  收藏  举报