Hướng dẫn giải của Bedao Regular Contest 21 - Xâu ghép


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Subtask 1:

For ~n \leq 20~, we can simply check all possible subsequences. Then check if that string satisfies being a grafted string.

Complexity: ~O(2^n)~.

Subtask 2: We will set ~a[i] = s[i] - 65 \quad \forall i = 1 \to n~.

Let ~cnt(c, i, j)~ be the number of characters ~c~ appearing in the range ~[i,j]~. We can quickly calculate this using a prefix sum array.

Let ~dp[i][j]~ be the longest subsequence ending at ~j~ with the ending character being ~i~.

We will have the formula:

~dp[a[i]][i] = \max(dp[a[j]][j]) \quad \forall j~ such that ~cnt(a[i], j, i) >= a[i]~ and ~a[j] < a[i]~.

Complexity: ~O(n^2)~.

Subtask 3:

For this subtask, we do not need to iterate through ~j~; instead, we will use the result from ~j-1~. And to find the position ~x~ such that ~cnt(c,x,j) = c~, we can use a prefix sum array combined with binary search or we can use a queue data structure.

$$dp[i][j] = dp[i][j-1]$$ $$dp[a[i]][i] = \max(dp[x-1][j]) \quad \forall j < a[i]$$.

Complexity: ~O(n\times 26)~.

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

using namespace std;

#define long long long

#define N 100005

int dp[27][N];

queue<int> q[27];

int main() {
    string s;
    cin >> s;

    s = " " + s;

    for(int i = 0;i < 27;i++)
        for(int j = 0;j < s.length();j++)
            dp[i][j] = 0;

    int res = 0;

    for(int i = 1;i < s.length();i++)
    {
        char c = s[i];
        int len = c - 'a' + 1;
        q[len].push(i);

        for(int j = 1;j <= 26;j++)
            dp[j][i] = dp[j][i-1];

        if(q[len].size() < len)
            continue;
        while(q[len].size() > len)
            q[len].pop();

        dp[len][i] = max(dp[len][i], len);
        int x = q[len].front();

        for(int j = 1;j < len;j++)
            dp[len][i] = max(dp[j][x-1] + len, dp[len][i]);

        res = max(res, dp[len][i]);
    }


    cout << res << endl;


    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.