写篇博客捋清一下思路
我们可以先算出一段区间的最优解将两个区间合并
对于一个区间记录4给状态vector[i][j] i,j属于{0,1}
代表以i开头,以j结尾的子序列状态,vector记录操作几次的最优状态
其中最优状态是经过诺干次操作后可以将字符串化成000(若干个0)11111(若干个1)
对于两个vector[i][j] vector[x][y]
合并成 vector[i][y]
一些细节就参考代码吧
//#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<numeric>
#include<cstring>//rfind("string"),s.find(string,begin)!=s.npos,find_first _of(),find_last_of()
#include<string>//to_string(value),s.substr(int begin, int length);
#include<cstdio>
#include<cmath>
#include<vector>//res.erase(unique(res.begin(), res.end()), res.end()),resize(n)//size of vector,vector<int>().swap(at[mx])
#include<queue>//priority_queue(big) /priority_queue<int, vector<int>, greater<int>> q(small)
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
#include<random>
#include<chrono>
//#include<ext/pb_ds/assoc_container.hpp>//gp_hash_table
//#include<ext/pb_ds/hash_policy.hpp>
//using namespace __gnu_pbds;
std::mt19937_64 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
using namespace std;
#define int long long//__int128 2^127-1(GCC)
#define PII pair<int,int>
const int inf = 0x3f3f3f3f3f3f3f3f, N = 1e5 + 5, mod = 1e9 + 7;
struct Info {
vector<int>f[2][2];
Info(){}
Info(char x, int p) {
if (x == '0') {
f[0][0].push_back(p);
}
else {
f[1][1].push_back(p);
}
}
};
void update(vector<int>& a,const vector<int>& b) {
if (a.size() < b.size()) {
a.resize(b.size(), -inf);
}
for (int i = 0; i < b.size(); i++) {
a[i] = max(a[i], b[i]);
}
}
vector<int> merge(const vector<int>& a, const vector<int>& b, int offset = 1) {
if (a.empty() || b.empty()) {
return{};
}
int i = 0, j = 0;
vector<int>c{ a[0] + b[0] };
if (offset) {
c.insert(c.begin(), -inf);
}
while (i + 1 < a.size() && j + 1 < b.size()) {
if (a[i + 1] - a[i] > b[j + 1] - b[j]) {
c.push_back(c.back() + a[i + 1] - a[i]);
i++;
}
else {
c.push_back(c.back() + b[j + 1] - b[j]);
j++;
}
}
while (i + 1 < a.size()) {
c.push_back(c.back() + a[i + 1] - a[i]);
i++;
}
while (j + 1 < b.size()) {
c.push_back(c.back() + b[j + 1] - b[j]);
j++;
}
return c;
}
Info merge(const Info& a, const Info& b) {
Info c = a;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
update(c.f[i][j], b.f[i][j]);
for (int k = 0; k < 2; k++) {
for (int l = 0; l < 2; l++) {
update(c.f[i][l], merge(a.f[i][j], b.f[k][l], (j && !k)));
}
}
}
}
return c;
}
signed main()
{
ios_base::sync_with_stdio(0); cin.tie(0), cout.tie(0);
int n;
cin >> n;
vector<char>c(n);
vector<int>p(n);
for (int i = 0; i < n; i++) {
cin >> c[i] >> p[i];
}
auto solve = [&](auto solve, int l, int r)->Info {
if (r - l == 1) {
return Info(c[l], p[l]);
}
int m = l + r >> 1;
auto res = merge(solve(solve, l, m), solve(solve, m, r));
return res;
};
auto ans = solve(solve,0, n);
int q;
cin >> q;
while (q--) {
int k;
cin >> k;
int res = 0;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
int d = min(k, (int)ans.f[i][j].size() - 1);
if (d >= 0) {
res = max(res, ans.f[i][j][d]);
}
}
}
cout << res << "\n";
}
}