题目 | Trees and Segments
Codeforces Round 893 (Div. 2)
D. Trees and Segments
https://codeforces.com/contest/1858/problem/D
3 seconds / 256 megabytes
standard input / standard output
Problem
The teachers of the Summer Informatics School decided to plant
The day of tree planting is tomorrow, and the day after tomorrow an inspector will come to the School. The inspector loves nature very much, and he will evaluate the beauty of the row as follows:
- First, he will calculate
as the maximum number of consecutive oaks in the row (the maximum substring consisting of zeros in the plan ). If there are no oaks in the row, then . - Then, he will calculate
as the maximum number of consecutive firs in the row (the maximum substring consisting of ones in the plan ). If there are no firs in the row, then . - Finally, he will calculate the beauty of the row as
for some — the inspector's favourite number.
The teachers know the value of the parameter , but for security reasons they cannot tell it to you. They only told you that is an integer from to .
Since the trees have not yet been planted, the teachers decided to change the type of no more than
For each integer
- What is the maximum beauty of the row of trees that the teachers can achieve by changing the type of no more than
trees if the inspector's favourite number is equal to ?
Input
The first line contains a single integer
The first line of each test case contains two integers
The second line contains a string
It is guaranteed that the sum of all
Output
For each test case, print
Example
Input
5
3 0
111
4 1
0110
5 0
10000
6 2
101101
7 1
0001101
Output
3 3 3
4 5 7 9
5 9 13 17 21
6 9 13 17 21 25
7 10 13 17 21 25 29
Note
In the first test case no changes are allowed, so
In the second test case for
- For
: , . The beauty of the row is . - For
: , . The beauty of the row is . - For
: , . The beauty of the row is . - For
: , . The beauty of the row is .
It can be shown that the changes described above are optimal for all from to .
题解
使用动态规划思想。
状态表示
其中,
状态计算
首先进行第一次状态转移:
经过这一次转移后,状态的含义是:花正好
这个
这样将所有状态进行递推取最大值,
复杂度
计算答案
题目所述的情况中,一定能找到一个分界点,让最长
上面的计算只计算了分界点左侧的数据,右侧的数据还未知。要解决这个问题,只需要将
如果字符串总长为
如果左边取
,右边取- 左边
串最长为: - 右边
串最长为:
- 左边
如果右边取
,左边取- 右边
串最长为: - 左边
串最长为:
- 右边
为了找到最优解,维护一个
最后把每种
代码
#include <bits/stdc++.h>
#define endl '\n'
// #define int long long
using namespace std;
void calc(vector<vector<vector<int>>> &dp, string &s, int k)
{
int n = s.size();
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= k; j++)
{
for (int m = 0; m < 2; m++)
{
int cost = (s[i] - '0') != m;
if (j + cost <= k)
{
dp[i + 1][j + cost][m] = max(dp[i + 1][j + cost][m], dp[i][j][m] + 1);
}
}
}
}
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= k; j++)
{
for (int m = 0; m < 2; m++)
{
if (i - 1 >= 0)
dp[i][j][m] = max(dp[i][j][m], dp[i - 1][j][m]);
if (j - 1 >= 0)
dp[i][j][m] = max(dp[i][j][m], dp[i][j - 1][m]);
}
}
}
}
void solve()
{
int n, k;
cin >> n >> k;
string s;
cin >> s;
vector<vector<vector<int>>> dp1(n + 10, vector<vector<int>>(k + 10, vector<int>(2)));
vector<vector<vector<int>>> dp2(n + 10, vector<vector<int>>(k + 10, vector<int>(2)));
calc(dp1, s, k);
reverse(s.begin(), s.end());
calc(dp2, s, k);
vector<int> l(n + 10, INT32_MIN);
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= k; j++)
{
for (int m = 0; m < 2; m++)
{
int a = dp1[i][j][m];
int b = dp2[n - i][k - j][m ^ 1];
if (m) // a=1, b=0
l[b] = max(l[b], a);
else // a=0, b=1
l[a] = max(l[a], b);
}
}
}
for (int i = n - 1; i >= 0; i--)
l[i] = max(l[i], l[i + 1]);
vector<int> ans(n + 10);
for (int i = 0; i <= n; i++)
for (int j = 1; j <= n; j++)
ans[j] = max(ans[j], i * j + l[i]);
for (int i = 1; i <= n; i++)
cout << ans[i] << " \n"[i == n];
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi