题意:
* 按照字典序的顺序从小写字母 a 开始按顺序给出序列 (序列中都
为升序字符串)
* a - 1
* b - 2
* ...
* z - 26
* ab - 27
* ...
* az - 51
* bc - 52
* ...
* vwxyz - 83681
* 输入字符串由小写字母 a-z 组成字符串为升序,根据字符串输出
在字典里的序列号为多少。
很容易地我们可以想到,设输入的字符串长度为len,我们可以用组合数求出所有小于len长度的字符串数量,(感觉这一步很好理解,反而许多题解给出了详细的证明?)。
然后我们开始求当前长度的字符串,一步一步逼近目标串。
因为它是依照字典序排序的,所以我们珂以利用这一性质确认从多少字母中选出多少个。
Code
1 //poj1850 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 6 using namespace std; 7 typedef long long ll; 8 9 int last,ans; 10 int c[50][50]; 11 char r[50]; 12 13 int C(int a,int b) 14 { 15 return c[a][b]; 16 } 17 18 void pre() 19 { 20 for(int i=0;i<=30;i++) c[i][0]=1; 21 for(int i=1;i<=30;i++) 22 for(int j=1;j<=i;j++) 23 c[i][j]=c[i-1][j]+c[i-1][j-1]; 24 } 25 26 int digit(int x) 27 { 28 return (int)r[x]-96; 29 } 30 31 int main() 32 { 33 pre(); 34 scanf("%s",r+1); 35 for(int i=1;i<strlen(r+1);i++) 36 if(r[i]>r[i+1]) {printf("0");return 0;} 37 for(int i=1;i<=strlen(r+1)-1;i++) 38 ans+=C(26,i); 39 for(int i=1;i<=strlen(r+1);i++) 40 { 41 int pos=digit(i); 42 for(int j=last+1;j<pos;j++) 43 ans+=C(26-j,strlen(r+1)-i); 44 last=pos; 45 } 46 printf("%d",ans+1); 47 return 0; 48 }
poj1850 Code【组合数学】By cellur925
原文:https://www.cnblogs.com/nopartyfoucaodong/p/9716118.html