计蒜客——字母排序

题目描述:

 XXXX年突然有外星人造访,但大家语言不通,不过科学家们经过研究发现外星人用26个英文字母组成的单词中最长不降子序列的长度来表述数字,且英文字母的排列顺序不同,现给出其排列顺序,再给出外星人说的每个数字(其实是每个英文单词,用空格隔开),翻译出外星人所说的数字(连续输出,最后加回车)。  (因为是最长不降子序列,所以数字中没有0,也就是说外星人的数字是> =1的数字)

例如

我们正常的字母排列顺序是abcdefg…….xyz,代表a< b< c< …..< x< y< z abcd  efg  hhh  ihg四个字符串的最长不降子序列的长度分别为4  3  3  1

输入格式:

第1,2行为字符串含义如题描述

输出格式:

输出答案含义如题描述

1< =第二行长度< =255

样例输入
abcdefghijklmnopqrstuvwxyz
abcd efg hhh ihg
样例输出
4331

题目分析:根据输入第一行给出的字典串(用于判断字母大小关系),求解第二行每个字符串的最长不降子序列,并依次输出最长不降子序列的大小。

方法分析:hash+dp;                                                                                                                      构造由字符到字符在字典串位置的映射关系 hash[c]=i+1;(c表示字典串里的字符,i表示字符c在字典串里的位置)。此时,问题转化成求解(数字串)最长不降子序列长度的问题。                 dp[i]表示以字符ss[i](ss表示第二行的字符串)结尾的字符串的最长不降子序列长度,分析可知,dp[i]是由字符ss[i]以前的所有字符共同决定。若hash[ss[i]]>=hash[ss[j]],说明ss[i]可以添加在ss[j]后面,形成不降子序列,故有dp[i]=max(dp[i],dp[j]+1)。


                     
                             
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <set>
#include <cmath>
#include <map>
#define maxn 1000
using namespace std;
int dp[maxn];
int Hash[maxn];
int main()
{
    string str,ss;
    cin>>str;//字典序
    for(int i=0;i<str.length();i++)
        Hash[str[i]]=i+1;
    while(cin>>ss){
        memset(dp,0,sizeof(dp));
        int maxlong=0;
        for(int i=0;i<ss.length();i++){
            dp[i]=1;//dp[i]的初始化
            for(int j=0;j<i;j++){
                if(Hash[ss[i]]>=Hash[ss[j]])
                    dp[i]=max(dp[i],dp[j]+1);
            }
            maxlong=max(maxlong,dp[i]);//注意:dp[ss.length()-1]不一定是最大值,因为最长不降子序列不一定包含最后一个字符。
        }
        cout<<maxlong;
    }
    cout<<endl;
    return 0;
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值