蚊子是这个世界上最可恶的生物。
题意
将英文小写字母组成的字符串进行编号,满足每个字母都比它前面那个字母大的字符串可以被编号,所有字符串按长度第一要素,同长度字典序决定的方法排序,”a”编号为1,给一个字符串,判断其是否可以编号,如果可以,编号是多少。
输入输出
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.
分析
我的做法是先DP求出开头字母为i,长度为j+1的可编号字符串的数量,dp[i][j]=SUM(dp[k][j-1]), k>i
然后找所有比输入字符串小的串,长度比输入小的可以任意开头,然后长度相等的,对每一位,读取从’a’到字符串字符前一个作为i,长度为剩余字符串长度的dp值。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define mxn 30
#define mxl 20
long long dp[mxn][mxl];
char a[mxl];
int len;
void set_dp(){
memset(dp,0,sizeof(dp));
for(int i=0;i<26;++i) dp[i][0]=1;
for(int j=1;j<10;++j)
for(int i=0;i<26;++i)
for(int k=i+1;k<26;++k)
dp[i][j]+=dp[k][j-1];
}
bool ok(){
for(int i=1;i<len;++i) if(a[i]<=a[i-1])
return false;
return true;
}
int main(){
set_dp();
while(scanf("%s",a)!=EOF){
len=strlen(a);
if(!ok()){ puts("0"); continue; }
long long ans=0;
for(int i=0;i<len-1;++i)
for(int j=0;j<26;++j)
ans+=dp[j][i];
for(int i=0;i<len;++i)
for(int j=(!i?0:a[i-1]-'a'+1);j<a[i]-'a';++j)
ans+=dp[j][len-i-1];
++ans;
cout<<ans<<endl;
}
return 0;
}