D. Balanced String
D. Balanced String
You are given a binary string (a binary string is a string consisting of characters 0 and/or 1).
Let's call a binary string balanced if the number of subsequences 01 (the number of indices and such that , and ) equals to the number of subsequences 10 (the number of indices and such that , and ) in it.
For example, the string 1000110 is balanced, because both the number of subsequences 01 and the number of subsequences 10 are equal to . On the other hand, 11010 is not balanced, because the number of subsequences 01 is , but the number of subsequences 10 is .
You can perform the following operation any number of times: choose two characters in and swap them. Your task is to calculate the minimum number of operations to make the string balanced.
Input
The only line contains the string () consisting of characters 0 and/or 1.
Additional constraint on the input: the string can be made balanced.
Output
Print a single integer — the minimum number of swap operations to make the string balanced.
Examples
input
101
output
0
input
1000110
output
0
input
11010
output
1
input
11001100
output
2
Note
In the first example, the string is already balanced, the number of both 01 and 10 is equal to .
In the second example, the string is already balanced, the number of both 01 and 10 is equal to .
In the third example, one of the possible answers is the following one: 11010 01110. After that, the number of both 01 and 10 is equal to .
In the fourth example, one of the possible answers is the following one: 11001100 11001010 11000011. After that, the number of both 01 and 10 is equal to .
解题思路
这题最关键的地方是要发现不管怎么交换字符,字符串中和的总数总是不变。
首先字符串中大小为的子序列无非就只有如下种:、、、。可以发现无论我们怎么交换,字符串中和的数量总是不变,因此和的总和也总是不变。假设字符串中的数量为,的数量为,那么就是定值,也意味着和的数量也总是不变,因为也是一个定值。由于题目保证一定可以得到平衡字符串,因此必然是偶数,意味着我们要通过最小的交换次数使得字符串中和的数量都等于。
问题可以等价成求最小的交换次数使得字符串中子序列的数量恰好为。可以发现交换相同字符是没有意义的,因此我们每次都应该交换和,相应的就会有两个不同位置的字符发生改变。为了方便我们把每一次的交换都记到变的位置,也就是说如果要把某个位置的变,那么交换的次数就加,而变的位置就不再统计(保证,出现的次数相同)。
因此可以定义状态表示交换后前个字符中有个且的数量为的所有方案中,交换次数的最小值。根据第个字符是还是进行状态划分。如果本身就是,那么就有状态转移方程
如果本身就是,那么就有状态转移方程
综合一下就有
最后答案就是。
AC代码如下,时间复杂度为:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 6 const int N = 110, M = N * N / 4; 7 8 char s[N]; 9 int f[N][N][M]; 10 11 int main() { 12 scanf("%s", s + 1); 13 int n = strlen(s + 1); 14 int s0 = 0, s1 = 0; 15 for (int i = 1; i <= n; i++) { 16 if (s[i] & 1) s1++; 17 else s0++; 18 } 19 int m = n * (n - 1) / 2 - s0 * (s0 - 1) / 2 - s1 * (s1 - 1) / 2 >> 1; 20 memset(f, 0x3f, sizeof(f)); 21 f[0][0][0] = 0; 22 for (int i = 1; i <= n; i++) { 23 for (int j = 0; j <= min(i, s0); j++) { 24 for (int k = 0; k <= m; k++) { 25 if (j) f[i][j][k] = f[i - 1][j - 1][k]; 26 if (k >= j) f[i][j][k] = min(f[i][j][k], f[i - 1][j][k - j] + (s[i] + 1) % 2); 27 } 28 } 29 } 30 printf("%d\n", f[n][s0][m]); 31 32 return 0; 33 }
参考资料
Educational Codeforces Round 153 Editorial:https://codeforces.com/blog/entry/119504
Educational Codeforces Round 153 (Rated for Div. 2) 详细题解(A~D):https://zhuanlan.zhihu.com/p/650743034
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17680838.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2022-09-05 Meeting Rooms III
2022-09-05 Number of Ways to Reach a Position After Exactly k Steps