zoukankan      html  css  js  c++  java
  • 最长升序子串(动态规划)

     【问题描述】输入一行字符串,该字符串只由小写英文字母a-z组成,且其中的字符可以重复,最长不超过10000个字符。
     从该字符串中按顺序挑选出若干字符(不一定相邻)组成一个新串,称为“子串”。如果子串中每两个相邻的字符或者相等,或者后一个比前一个大,则称为“升序子串”。编程求出输入字符串的最长升序子串的长度。
    例如,由输入字符串abdbch可以构成的升序子串有:abd、abch、bbch、abbch等。其中最长的升序子串是abbch,其长度为5。
     【输入形式】从标准输入读取一行字符串,该串不含空格,以回车符结束。
     【输出形式】向标准输出打印一个正整数,是字符串中最长的升序子串的长度,在行末要输出一个回车符。
     【输入样例】abdbch
     【输出样例】5
     【样例说明】abdbch中最长子串是abbch,长度是5。

    该题是动态规划题

    abdbch

    以seq[0]='a' 为结尾的最长子串长度为1

    以seq[1]='b' 为结尾的最长子串长度为2

    以seq[2]='d' 为结尾的最长子串长度为3

    以seq[3]='b' 为结尾的最长子串长度为3

    以seq[4]='c' 为结尾的最长子串长度为4

    以seq[5]='h' 为结尾的最长子串长度为5
    状态转移方程:

    if      max{resultLen[j] | seq[i]>=seq[j]| 0<=j<i  } 不为空集   resultLen[i]= max{resultLen[j] | seq[i]>=seq[j]| 0<=j<i  } + 1       

    else                                                                                   resultLen[i]=1                                                                              

    resultLen[0]=1,

    resultLen[1]:   对应的字符是b,b肯定能接在a后面 =>resultLen[1]=resultLen[0]+1=2。
    resultLen[2]:   resultLen[2]=max{resultLen[0],resultLen[1]} + 1 = 3
    resultLen[3]:   resultLen[3]= max{resultLen[0],resultLen[1]} + 1 = 3
    resultLen[4]:   resultLen[4] = max{resultLen[0],resultLen[1],resultLen[3]} + 1 = 4
    resultLen[5]:   resultLen[5] = max{resultLen[0],resultLen[1],resultLen[2],resultLen[3],resultLen[4]} + 1 = 5

    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<string>
    #include<stdio.h>
    using namespace std;
    #define N 26
    #define maxLen 10000
    string LestIncSubStr(string seq){
        int resultLen[maxLen]; //resultLen[i]表示以第i+1个输入字符为结尾的最长升序子列
        string resultSeq = "";
        resultLen[0] = 1;//很明显以第一个输入字符为结尾的最长升序子列的长度为1
        for (int i = 1; i < seq.length(); ++i){ //每次循环算出一个resultLen
            resultLen[i] = 1;
            for (int j = 0; j < i; ++j){ //遍历之前已经算出的resultLen数组
                if (seq[i] >= seq[j] && resultLen[i] < resultLen[j] + 1){
                    resultLen[i] = resultLen[j] + 1;
                }
            }
        }
        
        int len = *(std::max_element(&resultLen[0], &resultLen[seq.length()])); //对于数组int array[length],开始位置为&array[0],结束位置是&array[length],&array[length]为最后一个元素的后一个位置,与迭代器的iterator.end()是一个作用
        cout << "最长升序子列的长度为:" << len << endl;
        //计算子序列的具体内容
        int index;
        for (int i = 0; i < seq.length(); ++i){  
            if (resultLen[i] == len){  //找到以seq[index]为结尾的最长子序列
                index = i;
                resultSeq.push_back(seq[i]);//将子序列的最后一个字符加入
            }
        }
        while (len != 1 ){
            for (int j = 0; j < seq.length(); ++j){
                if (seq[index] >= seq[j] && len == resultLen[j] + 1){//
                    len--;
                    index = j;
                    resultSeq.insert(resultSeq.begin(), seq[j]);
                }
            }
        }
        cout << "最长子序列为:" << resultSeq;
        return "";
    }
    int main(){
        string seq;
        cin >> seq;
        LestIncSubStr(seq);
        system("pause");
        return 0;
    }
  • 相关阅读:
    uitableview中文排序问题
    跳转到指定页面popToViewController用法
    [__NSCFConstantString size]: unrecognized selector sent to instance 错误
    [NSThread sleepForTimeInterval:3.0];
    XCode 4.3 Unable to load persistent store UserDictionary.sqlite 以及 ios simulator failed to install the application
    ios 6.0模拟器页面调出pop窗口消失后无法使用键盘
    iOS真机测试,为Provisioning添加设备
    [IOS笔记]
    UITableView 滚动时使用reloaddata出现 crash'-[__NSCFArray objectAtIndex:]: index (1) beyond bounds (0)' Crash
    C# 自定义用户控件
  • 原文地址:https://www.cnblogs.com/codeDog123/p/6665031.html
Copyright © 2011-2022 走看看