计蒜客T42256硬币--题解
Posted huoshihongqwq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计蒜客T42256硬币--题解相关的知识,希望对你有一定的参考价值。
题面
题面
原题面:
小 B 面前的桌子上有 (n) 个硬币,(0) 表示正面,(1) 表示反面,只有当这 (n) 个硬币都是 (0) 朝上的时候这个他才能把这些钱收起来。现在他可以一个这样的操作来翻硬币,他选择一个 (x),把 (1) 到 (x) 位置上的硬币都翻面,他现在想知道最少需要多少次操作能使所有硬币正面朝上
题目描述
给定一个长度为(n)的(01)串(s),(s_i in { 0,1 })
每次可以选择一个(x),使得([1,x])之间的所有元素反转,即(0
ightarrow 1,1
ightarrow 0)
问最少需要多少次可以把所有的元素变为(0)。
输入格式
第一行:一个非负整数(n),表示串(s)的长度。
第二行:串(s),第(i)个字符表示(s_i)
输出格式
输出最小的操作次数。
样例输入(1)
4
1001
样例输出(1)
3
样例输入输出(1)解释
第一次操作:(x = 4),串(s)变为(0110)
第二次操作:(x = 3),串(s)变为(1000)
第三次操作:(x = 1),串(s)变为(0000)
可以证明,最小需要(3)次可以将(s)中所有元素变为(0)。且没有一种方案比这种方案更优。
样例输入(2)
5
10010
样例输出(2)
3
样例输入输出(2)解释
第一次操作:(x = 4),串(s)变为(01100)
第二次操作:(x = 3),串(s)变为(10000)
第三次操作:(x = 1),串(s)变为(00000)
可以证明,最小需要(3)次可以将(s)中所有元素变为(0)。且没有一种方案比这种方案更优。
数据规模与约定
对于(30\%)的数据:(1 leq n leq 20)
对于另(20\%)的数据:所有(s_i)都相等
对于(100\%)的数据:(1 leq n leq 10^6)
题解
慢慢挖掘题目性质。
性质1:答案与操作的顺序无关
证明:
显而易见,无需证明
设(p_i)为(s)转化成目标串的过程中,(s_i)被反转的最小次数
(p_i)一定是非负整数
性质2:
当(s_i = 0)时,(p_i)一定是偶数;
当(s_i = 1)时,(p_i)一定是奇数;
证明:
显然,不用证明。
性质3:(p_1)就是(s)转化为目标串的最小操作次数
证明:
由于每次操作都是([1,x]),都动了(s_1)。
所以(s_1)被反转的次数就是转化为目标串的最小次数。
性质4:(forall p_i geq p_{i + 1} (1 leq i leq n)),即(p)单调不增
证明:
对于(i,j),(i < j)
则(p_i geq p_j)
因为每次动到(j)的时候,(i)肯定被动到了。
所以(p_i geq p_j)
即,(p)单调不增。
***
性质5:(max _{1 leq i leq n} { p_i} = p_1)
证明:
由性质4得来。
结合以上所有性质。
目标是要求操作次数最小,所以就是要求(p_1)最小。
要求(p_1)最小,由于性质5,所以目标就是要求这个序列(p)尽量小。
这样才能保证最大的最小。
因为(p_i)是非负整数,我们考虑倒推。
并且要保证不破坏以上所有性质。
当(s_n = 0)时,显然,(p_n = 0)
当(s_n = 1)时,显然,(p_n = 1)
我们开始递推:
对于第(i (1 leq i leq n-1))位
如果(s_i = s_{i+1}),则,(p_i = p_{i+1})
如果(s_i
ot ={s_{i+1}}),则,(p_i = p_{i+1} + 1)
***
综上,递推完之后,(p_1)就是答案。
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
#define maxn 1000000
int p[maxn + 10];
int main()
{
int n;
string s;
cin>>n>>s;
if(s[s.size() - 1] == '0')
{
p[s.size() - 1] = 0;
}else
{
p[s.size() - 1] = 1;
}//判断最后一位
for(int i = s.size() - 2;i >= 0;i--)//倒推
{
if(s[i] == s[i + 1])
{
p[i] = p[i + 1];
}else
{
p[i] = p[i + 1] + 1;
}//递推公式
}
cout<<p[0];//输出第一个的p
return 0;
}
复杂度(Theta (n))
以上是关于计蒜客T42256硬币--题解的主要内容,如果未能解决你的问题,请参考以下文章
[计蒜客] ACM-ICPC 2018 南京赛区网络预赛 | 部分题解 | 线段树 + 线性筛 + 最短路