题
给定一个大写英文字母串,问最多能将原串分为多少个形如
C
A
T
CAT
CAT 或
T
A
T
TAT
TAT 的子序列?
如
C
A
T
A
T
CATAT
CATAT,仅能分出一个。而
C
A
T
T
A
T
CATTAT
CATTAT 可以分出两个。
串长
≤
1000000
\le 1000000
≤1000000。
解
有贪心解法也有二分解法。由于这题数据允许二分通过,并且二分的编程难度要小,所以考场上的正确决策应该写二分。二分有多少个
T
T
T 在末端,然后贪心地取即可。
贪心的方法具体是:从右往左为每个
T
T
T 匹配最近的
A
A
A,再为每个
A
A
A 匹配最近的
C
C
C 或
T
T
T。
代码如下:
#include <cstdio>
#include <cstring>
#define R register
char str[1000001];
int main()
{
R int T;scanf("%d",&T);
while(T--)
{
scanf("%s",str);
R int len=strlen(str);
while(str[len-1]!='T'&&len>0)--len;
R int l=0,r=len/3+1;
while(r-l!=1)
{
R int mid=(l+r)>>1,cnta=0,cntt=0,cntc=0;
for (R int i=len-1;i>=0;--i)
{
if(str[i] == 'T')
{
if(cntt < mid) ++cntt;
else if(cntc < cnta) ++cntc;
}
else if(str[i] == 'A' && cnta < cntt) ++ cnta;
else if(str[i] == 'C' && cntc < cnta) ++ cntc;
}
cntc==mid?l=mid:r=mid;
}
printf("%d\n",l);
}
}