设 表示为前
个数全取到
的最少操作次数。因为数组存不下,但是最多要存的数也就
个,实际上更少,所以这里可以采用 unordered_map,且每个数只能从上一个数能取到的转移过来,如果上一个数取不到
那么也就没必要转移了,最后就看
的最小值即可。
#include<bits/stdc++.h>
using namespace std;
using i64 = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i ++) {
cin >> a[i];
}
vector<unordered_map<int, int>> dp(n);
for (int i = 30; i >= 0; i --) {
auto x = a[0] >> i;
if (!dp[0].count(x)) {
dp[0][x] = i;
} else {
dp[0][x] = min(dp[0][x], i);
}
}
for (int i = 1; i < n; i ++) {
for (int j = 30; j >= 0; j --) {
auto x = a[i] >> j;
if (dp[i - 1].count(x)) {
if (!dp[i].count(x)) {
dp[i][x] = dp[i - 1][x] + j;
} else {
dp[i][x] = min(dp[i - 1][x] + j, dp[i][x]);
}
}
}
}
int ans = INT_MAX;
for (auto [_, num] : dp[n - 1]) {
ans = min(ans, num);
}
cout << ans << "\n";
return 0;
}

京公网安备 11010502036488号