列表

详情


NC24397. [USACO 2013 Mar G]Necklace

描述

Bessie the cow has arranged a string of N rocks, each containing a single letter of the alphabet, that she wants to build into a fashionable necklace.  
Being protective of her belongings, Bessie does not want to share her necklace with the other cow currently living on her side of the barn. The other cow has a name that is a string of M characters, and Bessie wants to be sure that this length-M string does not occur as a contiguous substring anywhere within the string representing her necklace (otherwise, the other cow might mistakenly think the necklace is for her). Bessie decides to remove some of the rocks in her necklace so that the other cow's name does not appear as a substring. Please help Bessie determine the minimum number of rocks she must remove.

输入描述

* Line 1: The first line is a length-N string describing Bessie's
initial necklace; each character is in the range "a" through
"z".

* Line 2: The second line is the length-M name of the other cow in the
barn, also made of characters from "a" to "z".

输出描述

* Line 1: The minimum number of stones that need to be removed from
Bessie's necklace so that it does not contain the name of the
other cow as a substring.

示例1

输入:

ababaa
aba

输出:

1

说明:

INPUT DETAILS:
For at least 20% of test cases, N <= 20.
For at least 60% of test cases, N <= 1000, M <= 100.
For all test cases, N <= 10000, M <= 1000.
For all test cases, M <= N.

OUTPUT DETAILS:
The modified necklace should be "abbaa".

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 33ms, 内存消耗: 604K, 提交时间: 2020-05-30 13:42:55

#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <string>

using namespace std;

int main() {
    string text, pattern;
    cin >> text >> pattern;

    int n = text.size();
    int m = pattern.size();

    for (int i = 0; i < n; ++i) {
        text[i] -= 'a';
    }
    
    for (int i = 0; i < m; ++i) {
        pattern[i] -= 'a';
    }

    vector<vector<int> > next(m, vector<int>(26, 0));

    for (int i = 1; i < m; ++i) {
        int prev = next[i - 1][pattern[i - 1]];
        next[i - 1][pattern[i - 1]] = i;
        for (int j = 0; j < 26; ++j) {
            next[i][j] = next[prev][j];
        }
    }
    next[m - 1][pattern[m - 1]] = m;

    vector<int> max_taken(m, -n - 1);
    max_taken[0] = 0;
    for (int i = 0; i < n; ++i) {
        vector<int> next_taken = max_taken;
        for (int j = 0; j < m; ++j) {
            int cur = next[j][text[i]];
            if (cur < m) {
                next_taken[cur] = max(next_taken[cur], max_taken[j] + 1);
            }
        }
        max_taken = next_taken;
    }

    int result = 0;
    for (int i = 0; i < m; ++i) {
        result = max(result, max_taken[i]);
    }

    cout << n - result << endl;
}

C++11(clang++ 3.9) 解法, 执行用时: 54ms, 内存消耗: 504K, 提交时间: 2020-06-01 14:08:20

#include<bits/stdc++.h>

using namespace std;

const int N = 1e4 + 10;
string S, s;
int n, m, nxt[N][30], dp[N], f[N];
int main() {
    cin >> S >> s;
    n = S.size(), m = s.size();
    for (int i = 0; i < n; i++) S[i] -= 'a';
    for (int i = 0; i < m; i++) s[i] -= 'a';
    for (int i = 1; i < m; i++) {
        int pr = nxt[i - 1][s[i - 1]];
        nxt[i - 1][s[i - 1]] = i;
        for (int j = 0; j < 26; j++) nxt[i][j] = nxt[pr][j];
    }
    nxt[m - 1][s[m - 1]] = m, dp[0] = 0;
    for (int i = 0; i < n; i ++) {
        for (int j = 0; j < m; j++) {
            int cur = nxt[j][S[i]];
            f[cur] = max(f[cur], dp[j] + 1);
        }
        memcpy(dp, f, sizeof dp);
    }
    int res = 0;
    for (int i = 0; i < m; i++) res = max(res, dp[i]);
    cout << n - res;
    return 0;
}

上一题