l0:最大连续0的个数,l1:最大连续1的个数
题目要求a*l0+l1的值最大
可以翻转k次操作
我们知道最大的连续0和最大连续1之间一定会有间隔
比如:0111111010000000000
前7位最大连续1的个数位6个,你的最大连续0的个数就一定要在第8位后面去找
于是我们可以用一个dp函数去找
dp[i][j]表示前i位翻转j次出现连续最大1的最大次数
dp2[i][j]表示后i位翻转j次出现连续0的最大次数
于是我们就可以知道当你要求前i位翻转j(j<=k)次时最大1的次数,你要找到最大0的次数就是在dp2[m-i][k-j]就是后m-i位翻转k-j次最大0的次数
然后再做一遍dp
dp[i][j]表示前i位翻转j次 最大0的次数
dp2[i][j]表示后i位翻转j次 最大1的次数
根据上面再做一遍
如果你开一个best[i]表示当你l1取i时你l0最大是多少,当然越大越好
#include<iostream>
#include<algorithm>
#include<numeric>//accumulate(be,en,0)
#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()),reverse(q.begin(),q.end()),vector<int>().swap(at[mx])
#include<queue>//priority_queue(big) /priority_queue<int, vector<int>, greater<int>> q(small)
#include<stack>
//#include<map>//unordered_map
#include<set>//iterator,insert(),erase(),lower(>=)/upper_bound(>)(value)/find()return end()
#include<unordered_map>
#include<unordered_set>
#include<bitset>//size,count(size of 1),reset(to 0),any(have 1?)
//#include<ext/pb_ds/assoc_container.hpp>//gp_hash_table
//#include<ext/pb_ds/hash_policy.hpp>
//using namespace __gnu_pbds;
#define int long long//__int128 2^127-1(GCC)
#define PII pair<int,int>
using namespace std;
const int inf = 0x3f3f3f3f3f3f3f3f, N = 1e5 + 5, mod = 1e9 + 7;
vector<vector<int>>calc(string& s, char c)
{
int n = s.size();
vector<vector<int>>ans;
vector<int>cur(n + 1, 0);
vector<int>pos;
pos.emplace_back(-1);
for (int i = 0; i < n; i++) {
ans.emplace_back(cur);
if (s[i] == c) pos.emplace_back(i);
int m = pos.size();
for(int j = 0; j < m; j++) {
cur[m - j - 1] = max(cur[m - j - 1], i - pos[j]);
}
for (int i = 1; i <= n; i++) cur[i] = max(cur[i], cur[i - 1]);
}
ans.emplace_back(cur);
return ans;
}
signed main()
{
ios_base::sync_with_stdio(0); cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--)
{
int n, k;
cin >> n >> k;
string s;
cin >> s;
vector<int>best(n + 1, -100000);
for (int z : {0, 1}) {
vector<vector<int>>dp = calc(s, '0');
reverse(s.begin(), s.end());
vector<vector<int>>dp2 = calc(s, '1');
reverse(dp2.begin(), dp2.end());
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= k; j++) {
best[dp[i][j]] = max(best[dp[i][j]], dp2[i][k - j]);
}
}
}
for (int i = 1; i <= n; i++) {
int ans = 0;
for (int j = 0; j <= n; j++) {
ans = max(ans, i * best[j] + j);
}
cout << ans << ' ';
}
cout << '\n';
}
}