比赛 2025暑期集训第6场 评测结果 C
题目名称 Moortal Cowmbat 最终得分 0
用户昵称 健康铀 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2025-07-12 11:45:49
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;

const int INF = 1e9;

class SegTree {
public:
    int n;
    vector<int> t;

    SegTree(int size) {
        n = size;
        t.resize(4 * n, INF);
    }

    void upd(int idx, int val, int v = 0, int l = 0, int r = -1) {
        if (r == -1) r = n - 1;
        if (l == r) {
            t[v] = val;
            return;
        }
        int m = (l + r) / 2;
        if (idx <= m) upd(idx, val, 2 * v + 1, l, m);
        else upd(idx, val, 2 * v + 2, m + 1, r);
        t[v] = min(t[2 * v + 1], t[2 * v + 2]);
    }

    int qry(int ql, int qr, int v = 0, int l = 0, int r = -1) {
        if (r == -1) r = n - 1;
        if (ql > qr) return INF;
        if (ql <= l && r <= qr) return t[v];
        int m = (l + r) / 2;
        int res = INF;
        if (ql <= m) res = min(res, qry(ql, qr, 2 * v + 1, l, m));
        if (qr > m) res = min(res, qry(ql, qr, 2 * v + 2, m + 1, r));
        return res;
    }
};

int main() {
	freopen("cowmbat.in","r",stdin);
	freopen("cowmbat.out","w",stdout);
    int N, M, K;
    fin >> N >> M >> K;
    string S;
    fin >> S;

    vector<vector<int>> a(M, vector<int>(M));
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < M; j++) {
            fin >> a[i][j];
        }
    }

    vector<vector<int>> dist = a;
    for (int k = 0; k < M; k++) {
        for (int i = 0; i < M; i++) {
            for (int j = 0; j < M; j++) {
                if (dist[i][k] + dist[k][j] < dist[i][j]) {
                    dist[i][j] = dist[i][k] + dist[k][j];
                }
            }
        }
    }

    vector<SegTree> st(M);
    for (int i = 0; i < M; i++) {
        st[i] = SegTree(N + 1);
        st[i].upd(0, 0);
    }

    vector<int> dp(N + 1, INF);
    dp[0] = 0;

    vector<vector<int>> pref(N + 1, vector<int>(M, 0));

    for (int i = 1; i <= N; i++) {
        int c0 = S[i - 1] - 'a';
        for (int c = 0; c < M; c++) {
            pref[i][c] = pref[i - 1][c] + dist[c0][c];
        }

        if (i >= K) {
            dp[i] = INF;
            for (int c = 0; c < M; c++) {
                int mn = st[c].qry(0, i - K);
                if (mn < INF) {
                    dp[i] = min(dp[i], mn + pref[i][c]);
                }
            }
            if (dp[i] < INF) {
                for (int c = 0; c < M; c++) {
                    st[c].upd(i, dp[i] - pref[i][c]);
                }
            }
        }
    }

    fout << dp[N] << endl;

    fin.close();
    fout.close();
    return 0;
}