题目
Transmitting and memorizing information is a task that requires different coding systems for the best use of the available space. A well known system is that one where a number is associated to a character sequence. It is considered that the words are made only of small characters of the English alphabet a,b,c, …, z (26 characters). From all these words we consider only those whose letters are in lexigraphical order (each character is smaller than the next character).
The coding system works like this:
- The words are arranged in the increasing order of their length.
- The words with the same length are arranged in lexicographical order (the order from the dictionary).
- We codify these words by their numbering, starting with a, as follows:
a - 1
b - 2
…
z - 26
ab - 27
…
az - 51
bc - 52
…
vwxyz - 83681
…
Specify for a given word if it can be codified according to this coding system. For the affirmative case specify its code.
input
The only line contains a word. There are some constraints:
- The word is maximum 10 letters length
- The English alphabet has 26 characters.
output
The output will contain the code of the given word, or 0 if the word can not be codified.
sample
input: bf
output: 55
问题陈述
按照题目给出的例子,给出字母串表标号。
题目中给出的字母串中字母是“单调递增”的,也就是没有重复,后一个要大于前一个
思路
所谓“标号”,就是某一个字母串前面的字母串个数+1
问题转化为求字母串前面的字母串个数
某一个字母串前面的字母串有三种情况:
- 长度小于该字母串
- 长度等于该字母串,首字母小于该字母串首字母
- 长度和首字母都与该字母串相等,但位置更靠前
因为后面的字母串对前面的字母串有包含的关系,所以考虑用动态规划来求解,那接下来的重点就是寻找状态转移方程了
用$dp[i][j]$表示长度为$i$首字母为$j$的字母串个数,那么$dp[i+1][j]=dp[i][j+1]+dp[i][j+2]+···+dp[i][‘z’-i]$
光看公式可能理解得不是很好,举个例子吧:
比如我们现在想求长度是5位,b打头的字母串的个数:
b _ _ _ _ ······$dp[5][b]$
那么考虑后面的四位,有下面的22种情况:
b ++c++ _ _ _ ······$dp[4][c]$
b ++d++ _ _ _ ······$dp[4][d]$
b ++e++ _ _ _ ······$dp[4][e]$
···
b ++w++ ++x++ ++y++ ++z++ ······$dp[4][w]$
把上面的22种情况相加,就可以得到长度为5,b打头的所有字母串个数$p[5][b]$
对于其中的$dp[4][j]$也应用上述的方法可以求解
有了上面的思路,就可以由最初的$dp[1][j]=1$逐步求出完整的$dp[i][j]$表了!
好开心是不是,下面算个题试试好不好用吧:
假如我们现在要求字母串“cefkq”的序号,也就是这个字母串前面有多少个。回头看那三种情况:
- 长度小于该字母串 —— 把所有的$dp[4][j]$,$dp[3][j]$,$dp[2][j]$,$dp[1][j]$加起来
- 长度等于该字母串,首字母小于该字母串首字母 —— $dp[5][a]$,$dp[5][b]$加起来
- 长度和首字母都与该字母串相等,但位置更靠前
嗯,问题解决了一大部分了,现在就剩第三种情况了!!!!
再看一眼字母串“cefkq”
长度和首字母都相等,位置比它在前面,那就一位一位考虑呗
第二位是e,
c ++d++ _ _ _在它前面!所以又有$dp[4][d]$个在它前面的,加上!
第三位是f,ef中间没有其他字母了,继续往后看
第四位是k,fk中间还有g、h、i、j
c e ++g++ _ _ ······$dp[3][g]$
c e ++h++ _ _ ······$dp[3][h]$
c e ++i++ _ _ ······$dp[3][i]$
c e ++j++ _ _ ······$dp[3][j]$
统统加上!
······
再往后就跟前面一样了,不再赘述了
到这,问题解决了,上代码
代码
|