题目描述
- You are given a string s consisting of characters 0 and/or 1.
- You have to remove several (possibly zero) characters from the beginning of the string, and then several (possibly zero) characters from the end of the string. The string may become empty after the removals. The cost of the removal is the maximum of the following two values:
- he number of characters 0 left in the string;
- the number of characters 1 removed from the string.
What is the minimum cost of removal you can achieve?
题意
给定一个01串,任意截取一段子串(可空),使花费最小
花费计算方法:max(区间内的0的个数, 区间外的1个数)
思路
- l,r指针用于选择截取的子串区间
- 显然当r的下一个元素是’1’时,r必须++,因为这样减少了区间外1的个数,对得到更优的答案有利;同理l当前所指元素为’0’时,l必须++.
- 经过上面的操作,r的下一个元素一定是’0’,l所指元素一定是’1’.两个指针向后移动都对得到更优的结果不利.现在要决定下面该移动哪个指针:
如果区间内0的个数>区间外1的个数,那么想要得到更优的答案,就要减少区间内0的个数,那么就要缩小区间范围,即l++;同理,相反情况r++.
code
#include<bits/stdc++.h>
// #define DEBUG(x) #x<<':'<<(x)<<' '
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
// const int mod=1e9+7;
void solv()
{
string s;
int left0,del1,l,r,ans;
cin>>s;
int num0=0,num1=0,n=s.size();
for(int i=0;i<n;i++)
if(s[i]=='0')num0++;
else num1++;
left0=0;
del1=num1;
ans=del1;
l=0,r=-1;
// max(0 left , 1 deleted)
do
{
while(r+1<n&&s[r+1]=='1')
{
r++;
del1--;
}
while(l+1<=r&&s[l]=='0')
{
l++;
left0--;
}
ans=min(max(left0,del1),ans);
if(left0<=del1)
{
r++;
left0++;
}
else
{
l++;
del1++;
}
ans=min(max(left0,del1),ans);
}while((l<=r&&r<n));
cout<<ans<<'\n';
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int T=1;
cin>>T;
while(T--)
{
solv();
}
return 0;
}