看了一眼题解,都是dp做的,其实n<=500的话,直接枚举四个块的位置,然后讨论0101和1010两种情况也能过(
具体每个块里面要操作多少次,可以通过前缀和求出这个块中原本1的个数 x ,如果这块最后要求全0则要操作x次,要求全1则要操作len-x次(len为块的长度)
答案取所有情况的最小值即可。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using lll = __int128;
using pll = pair<ll, ll>;
#define fp(i, l, r) for(int i=(l); i<=(r); ++i)
#define fq(i, l, r) for(int i=(r); i>=(l); --i)
#define fi first
#define se second
#define debug(x) cerr << #x << ": " << x << '\n';
const int N = 2e5 + 10;
const ll MOD = 998244353;
const ll INF = 0x3f3f3f3f3f3f3f3f;
void init() {
}
void solve() {
ll n;
cin >> n;
string s;
cin >> s;
s = " " + s;
vector<ll> pre(n + 1);
fp(i, 1, n) {
if (s[i] == '1') pre[i] = pre[i - 1] + 1;
else pre[i] = pre[i - 1];
}
ll ans = 1e10;
fp(i, 1, n - 3) fp(j, i + 1, n - 2) fp(k, j + 1, n - 1) {
ans = min(ans, abs(pre[i] - 0) + abs(pre[j] - pre[i] - (j - i)) +
abs(pre[k] - pre[j] - 0) + abs(pre[n] - pre[k] - (n - k)));
ans = min(ans, abs(pre[i] - i) + abs(pre[j] - pre[i] - 0) +
abs(pre[k] - pre[j] - (k - j)) + abs(pre[n] - pre[k] - 0));
}
cout << ans;
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
init();
int _ = 1;
// cin>> _;
while (_--)
solve();
return 0;
}

京公网安备 11010502036488号