[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);
}