问题重述:
用26个小写字母进行编码,编码规则如下:
1)每个编码中前一个字母必须小于后一个字母
2)编码按照长度从小到大排列,相同长度按字典序进行排列
输入一个字母串,求解该编码对应的数值。
问题分析:
该问题等价于求解小于输入编码的编码的数目。
对于编码X = x1,x2,x3,...xk, 小于X的编码可以分为两个部分
1)位数小于k的编码。
这部分编码的数目 = C[26][1] + C[26][1] + ... + C[26][k - 1]
2)长度为k,且小于X的编码。
假设Y为满足该条件的编码,现只需确定Y的数目。从左到右遍历编码X: i = 1 to k,假设X和Y的前i - 1位均相等且 yi != xi,那么 yi 必须满足 xi-1 = yi - 1 < yi < xi。
对于yi的每一种取值, yi, yi + 1, ... yk只需满足递增关系即可, 共有C[26][25 - (yi - 'a')]种编码。
根据以上分析,即可求出结果。
AC代码:
//Memory: 204K Time: 0MS #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> using namespace std; string s, ss; ][]; void init() { ; i <= ; i++) c[i][] = c[i][i] = ; ; i <= ; i++) ; j < i; j++) c[i][j] = c[i - ][j] + c[i - ][j - ]; } int main() { cin >> s; int len = s.size(); ; i < len - ; i++) { ] || s[i] == s[i + ]){ cout << << endl; ; } } init(); ; ; i <= len - ; i++) { ans += c[][i]; } ; i < s[] - 'a'; i++) { ans += c[ - i][len - ]; } ; i < len; i++) { ] - ; j < s[i] - 'a'; j++) ans += c[ - j][len - - i]; } cout << ans + << endl; ; }