zoukankan      html  css  js  c++  java
  • hihoCoder1690 (动态规划)

    #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
    ",MAXu+MAXi);
        return 0;
    }
    View Code




  • 相关阅读:
    HDU_2191_多重背包
    HDU_1494_dp
    POJ_1088_dfs
    所有的畅通工程[HDU1232][HDU1874][HDU1875][HDU1879]
    畅通工程[HDU1863]
    还是畅通工程[HDU1233]
    最小生成树
    Who's in the Middle[HDU1157]
    Bungee Jumping[HDU1155]
    Is It A Tree?[HDU1325][PKU1308]
  • 原文地址:https://www.cnblogs.com/ACRykl/p/8450054.html
Copyright © 2011-2022 走看看