优化枚举2

[Algo] 优化枚举2

1. K个逆序对数组

// 1. K个逆序对数组
// https://leetcode.cn/problems/k-inverse-pairs-array/
int kInversePairs(int n, int k) {
    vector<vector<int>> dp(n + 1, vector<int>(k + 1, 0));
    // dp[i][j]: 1...i构成逆序对数量为j的排列数
    dp[0][0] = 1;
    for (int i = 1; i <= n; i++) {
        dp[i][0] = 1;
        int window = 1; 
        for (int j = 1; j <= k; j++) {
            if (i > j) {
                window = (window + dp[i - 1][j]) % MOD;
            } else {
                window = ((window + dp[i - 1][j]) % MOD - dp[i - 1][j - i] + MOD) % MOD;
            }
            dp[i][j] = window;
        }
    }
    return dp[n][k];
}

2. 自由之路

// 2. 自由之路
// https://leetcode.cn/problems/freedom-trail/
int clock(vector<vector<int>>& position, int cur, char target) {
    int index = target - 'a';
    int l = 0, r = position[index].size() - 1, m;
    int ans = -1;
    while (l <= r) {
        m = (l + r) / 2;
        if (position[index][m] > cur) {
            ans = m;
            r = m - 1;
        } else {
            l = m + 1;
        }
    }
    return ans != -1 ? position[index][ans] : position[index][0];
}
int counterClock(vector<vector<int>>& position, int cur, char target) {
    int index = target - 'a';
    int l = 0, r = position[index].size() - 1, m;
    int ans = -1;
    while (l <= r) {
        m = (l + r) / 2;
        if (position[index][m] < cur) {
            ans = m;
            l = m + 1;
        } else {
            r = m - 1;
        }
    }
    return ans != -1 ? position[index][ans] : position[index][position[index].size() - 1];
}
int func1(vector<vector<int>>& position, string& ring, string& key, int cur, int index, vector<vector<int>>& dp) {
    int n = ring.length(), m = key.length();
    if (index == m) return 0;
    if (dp[cur][index] != -1) return dp[cur][index];
    int ans;
    if (ring[cur] == key[index]) {
        ans = 1 + func1(position, ring, key, cur, index + 1, dp);
    } 
    else {
        int pos1 = clock(position, cur, key[index]);
        int distance1 = (pos1 - cur + n) % n;
        int pos2 = counterClock(position, cur, key[index]);
        int distance2 = (cur - pos2 + n) % n;
        if (pos1 == pos2) {
            ans = 1 + min(distance1, distance2) + func1(position, ring, key, pos1, index + 1, dp);
        }
        else {
            ans =  1 + min(distance1 + func1(position, ring, key, pos1, index + 1, dp), distance2 + func1(position, ring, key, pos2, index + 1, dp));
        } 
    }
    dp[cur][index] = ans;
    return ans;
}
int findRotateSteps(string ring, string key) {
    int n = ring.length(), m = key.length();
    vector<vector<int>> position(26);
    for (int i = 0; i < n; i++) {
        int index = ring[i] - 'a';
        position[index].push_back(i);
    }
    vector<vector<int>> dp(n, vector<int>(m, -1));
    return func1(position, ring, key, 0, 0, dp);
}
posted @ 2025-03-28 10:51  yaoguyuan  阅读(15)  评论(0)    收藏  举报