题目描述:
小b有一个01序列,她每次可以翻转一个元素,即将该元素从0变1或者从1变0。
现在她希望序列不降,求最少翻转次数。
收起
输入
第一行输入一个数n,其中1≤n≤20000; 第二行输入一个由‘0’和‘1’组成的字符串
输出
输出一个非负整数,表示翻转次数
输入样例
6 010110
输出样例
2
题解:
序列不降的情况:
1.00000
2.111111
3.000111
也就是选定一个位置把此位置之前的1翻转为0,之后的1翻转为0以保证序列不降。
故可利用前、后缀和统计每一个位置之前(包括此位置)的1的个数和这个位置之后的0的个数。
枚举1~n个位置,计算每个位置前缀1的数量和后缀0的数量的和得到的值便为此位置的ans,枚举出最小值。
Code:
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
char s[20010];
int a[20010][2];
int n,sum=0x3f3f3f3f;
cin>>n>>s;
a[0][0]=a[0][1]=0;
for(int i=0;i<n;i++)
{
a[i+1][0]=a[i][0];
a[i+1][1]=a[i][1];
if(s[i]=='0') a[i+1][0]++;
else a[i+1][1]++;
}
for(int i=0;i<=n;i++)
{
sum=min(sum,a[i][1]+a[n][0]-a[i][0]);
}
cout<<sum;
return 0;
}