2517 最少01翻转次数
基准时间限制:2.0 秒 空间限制:262,144.0 KB
小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,枚举出最小值。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn =2e4+10;
int n,ans;
char a[maxn];
int z[maxn],o[maxn];
int main ()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]=='1')
o[i]=o[i-1]+1;
else
o[i]=o[i-1];
}
for(int i=n;i>=1;i--)
{
if(a[i]=='0')
z[i]=z[i+1]+1;
else
z[i]=z[i+1];
}
ans=n;
for(int i=1;i<=n+1;i++)
{
ans=min(ans,o[i-1]+z[i]);
}
cout<<ans;
}
仅为个人理解,若有纰漏欢迎指出。