#1690 : AEIOU
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给定一个只包含aeiou的字符串S,请你找到其中的最长的子序列,满足:
1. 所有的a都在e和i之前,所有的e都在i之前;
2. 所有的o都在u之前。
输出最长满足条件的子序列的长度。
例如对于S = aeiouaeiou,满足条件的最长的子序列有 aoaeiou, aeiouiu等。长度都是7。
输入
输入只有一行,字符串S。
对于50%的数据,1 ≤= |S| ≤ 1000
对于100%的数据,1 ≤= |S| ≤ 1000000
输出
一个整数,表示答案。
- 样例输入
-
aeiouaeiou
- 样例输出
-
7
分析:最长子列必有a->e->i,o->u,先求所有a在e前,所有e在i前的最长子列,
再求所有o在u之前的最长子列,答案为两个最长子列的和,
设MAXa,MAXe,MAXi分别表示前k个字符中以a,e,i结尾的最长子列长度,
则 MAXa=MAXa+1,s[k]==‘a‘;
MAXe=max(MAXa,MAXe)+1,s[k]==‘e‘;
MAXi=max(MAXa,MAXe,MAXi)+1,s[k]==‘i‘;
同理,MAXo,MAXu分别表示前k个字符中以o,u结尾的最长子列长度,
则 MAXo=MAXo+1,s[k]==‘o‘;
MAXu=max(MAXo,MAXu)+1,s[k]==‘u‘;
最后结果为MAXi+MAXu#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int max(int a,int b,int c) { if(a<b) a=b; if(a<c) a=c; return a; } char s[2000000]; int main() { scanf("%s",s); int k=0; int MAXa=0,MAXe=0,MAXi=0,MAXo=0,MAXu=0; while(s[k]) { if(s[k]==‘a‘) MAXa++; else if(s[k]==‘e‘) MAXe=max(MAXa,MAXe)+1; else if(s[k]==‘i‘) MAXi=max(MAXa,MAXe,MAXi)+1; else if(s[k]==‘o‘) MAXo++; else MAXu=max(MAXo,MAXu)+1; k++; } printf("%d\n",MAXu+MAXi); return 0; }