CSES - Datatähti 2022 loppu - Results
Submission details
Task:Peli
Sender:MojoLake
Submission time:2024-10-09 21:30:41 +0300
Language:C++ (C++20)
Status:READY
Result:42
Feedback
groupverdictscore
#1ACCEPTED11
#2ACCEPTED31
#30
Test results
testverdicttimegroup
#1ACCEPTED0.05 s1, 2, 3details
#2ACCEPTED0.36 s2, 3details
#3--3details
#4ACCEPTED0.00 s1, 2, 3details
#5ACCEPTED0.00 s1, 2, 3details

Code

#pragma GCC optimize("03,unroll-loops")
#include <vector>
#include <iostream>
// #include <cassert>
#include <algorithm>

#define all(x) begin(x), end(x)

using namespace std;
using ll = long long;

template<typename S, typename T = S> void chmax(S &s, T t) {s = s > t ? s : t;}

const int N = 1e5 + 5;
const int K = 51;
const int inf = 1e9;

// int dp[N][K][K][3]; // i, 0: [a][b], 1: [a][c], 2: [b][c]
// vector<vector<vector<vector<int>>>> dp(
    //     N, vector<vector<vector<int>>>(K, vector<vector<int>>(K, vector<int>(3)))
    // );
vector<vector<vector<int>>> dp(K, vector<vector<int>>(K, vector<int>(3)));
vector<vector<vector<int>>> pre_dp(K, vector<vector<int>>(K, vector<int>(3)));
vector<vector<vector<int>>> new_dp(K, vector<vector<int>>(K, vector<int>(3)));

int n, k;

void rm(int i, int a, int b, int c, int pre) {
    // assert(a > 0 && b > 0 && c > 0);

    if (a == 1) {
        int m = 2; // [b][c]
        chmax(dp[b-1][c-1][m], pre + 1);
    }

    if (b == 1) {
        int m  = 1; // [a][c]
        chmax(dp[a-1][c-1][m], pre + 1);
    }

    if (c == 1) {
        int m = 0; // [a][b]
        chmax(dp[a-1][b-1][m], pre + 1);
    }
}

void m0(int i, int a, int b, char ch) {
    int m = 0; // [a][b]
    int pre = pre_dp[a][b][m];
    if (pre < 0)return; // previous state impossible

    // always: (not taking current character)
    chmax(dp[a][b][m], pre);

    if (a + b == k) return; // can't take current character

    if (ch == 'A') {
        chmax(dp[a+1][b][m], pre);
        return;
    } 

    if (ch == 'B') {
        chmax(dp[a][b+1][m], pre);
        return;
    } 
    // else ch == 'C'
    int c = 1;

    int mn = min({a, b, c});

    if (mn > 0) {
        rm(i, a, b, c, pre); // try removing different stuff
        return;
    }

    // now either a == 0 or b == 0
    // assert(a == 0 || b == 0);

    if (a == 0) {
        m = 2; // [b][c]
        chmax(dp[b][c][m], pre);
    }

    if (b == 0) {
        m = 1; // [a][c]
        chmax(dp[a][c][m], pre);
    }
}

void m1(int i, int a, int c, char ch) {
    int m = 1; // [a][c]
    int pre = pre_dp[a][c][m];
    if (pre < 0)return; // previous state impossible

    // always: (not taking current character)
    chmax(dp[a][c][m], pre);

    if (a + c == k) return; // can't take current character

    if (ch == 'A') {
        chmax(dp[a+1][c][m], pre);
        return;
    } 

    if (ch == 'C') {
        chmax(dp[a][c+1][m], pre);
        return;
    } 
    // else ch == 'B'
    int b = 1;

    int mn = min({a, b, c});

    if (mn > 0) {
        rm(i, a, b, c, pre); // try removing different stuff
        return;
    }

    // now either a == 0 or c == 0
    // assert(a == 0 || c == 0);

    if (a == 0) {
        m = 2; // [b][c]
        chmax(dp[b][c][m], pre);
    }

    if (c == 0) {
        m = 0; // [a][b]
        chmax(dp[a][b][m], pre);
    }
}

void m2(int i, int b, int c, char ch) {
    int m = 2; // [b][c]
    int pre = pre_dp[b][c][m];
    if (pre < 0)return; // previous state impossible

    // always: (not taking current character)
    chmax(dp[b][c][m], pre);

    if (b + c == k) return; // can't take current character

    if (ch == 'B') {
        chmax(dp[b+1][c][m], pre);
        return;
    } 

    if (ch == 'C') {
        chmax(dp[b][c+1][m], pre);
        return;
    } 
    // else ch == 'A'
    int a = 1;

    int mn = min({a, b, c});

    if (mn > 0) {
        rm(i, a, b, c, pre); // try removing different stuff
        return;
    }

    // now either b == 0 or c == 0
    // assert(b == 0 || c == 0);

    if (b == 0) {
        m = 1; // [a][c]
        chmax(dp[a][c][m], pre);
    }

    if (c == 0) {
        m = 0; // [a][b]
        chmax(dp[a][b][m], pre);
    }
}

void fill_with_inf(vector<vector<vector<int>>>& x) {
    for (int a = 0; a <= k; ++a) {
        for (int b = 0; a + b <= k; ++b) {
            for (int m = 0; m < 3; ++m) {
               x[a][b][m] = -inf;
            }
        }
    }
}

int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> k;
    string s; cin >> s;
    s = "#" + s;

    fill_with_inf(pre_dp);
    fill_with_inf(dp);
    fill_with_inf(new_dp);
    pre_dp[0][0][0] = pre_dp[0][0][1] = pre_dp[0][0][2] = 0;

    int ans = 0;

    for (int i = 1; i <= n; ++i) {
        char ch = s[i];
        for (int e = 0; e <= k; ++e) {
            for (int f = 0; e + f <= k; ++f) {
                for (int m = 0; m < 3; ++m) {
                    m0(i, e, f, ch);
                    m1(i, e, f, ch);
                    m2(i, e, f, ch);
                }
            }
        }
        // fill_with_inf(new_dp);
        swap(pre_dp, dp);
        swap(dp, new_dp);
    }
    
    for (int a = 0; a <= k; ++a) {
        for (int b = 0; a + b <= k; ++b) {
            for (int m = 0; m < 3; ++m) {
                chmax(ans, pre_dp[a][b][m]);
            }
        }
    }
    
    cout << ans << "\n";

}

Test details

Test 1

Group: 1, 2, 3

Verdict: ACCEPTED

input
100000 3
BBAACBCBACBACABBCBAABCBCCBCCAA...

correct output
18201

user output
18201

Test 2

Group: 2, 3

Verdict: ACCEPTED

input
100000 10
BAACABCCBCBAACBBCCCCABBBBACCBA...

correct output
29684

user output
29684

Test 3

Group: 3

Verdict:

input
100000 50
ACAABCBBAAAACCBBABACACACBCAACA...

correct output
32740

user output
(empty)

Test 4

Group: 1, 2, 3

Verdict: ACCEPTED

input
3 1
ABC

correct output
0

user output
0

Test 5

Group: 1, 2, 3

Verdict: ACCEPTED

input
3 2
ABC

correct output
0

user output
0