poj1496 Word Index / poj1850 Code(组合数学)
题意:输出若干个给定的字符串($length<=10$)在字典序中的位置,字符串中的字母必须严格递增。
读取到非法字符串时,输出“0”,终止程序。(poj1496:继续读取)
我们分成2种情况讨论字典序小于给定字符串的字符串个数
1.长度比给定字符串小
其实长度为$i$的字符串的个数就是$C(26,i)$
因为我们随机选取$i$个字符后,从小到大依次取出,是可以保证字符串是有序的。
2.长度等于给定字符串
我们枚举每一位,计算从该位开始小于给定字符串的个数,同样可以用组合数计算。
预处理组合数一下........
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define re register 5 using namespace std; 6 char a[20]; 7 int C[30][30]; 8 int main(){ 9 for(int i=1;i<=26;++i) 10 for(int j=0;j<=i;++j)//组合数预处理 11 C[i][j]=(!j||i==j)?1:C[i-1][j]+C[i-1][j-1]; 12 while(cin>>a){//用scanf就OLE(大雾) 13 int len=strlen(a),ans=1; bool flag=0; 14 for(int i=1;i<len;++i) 15 if(a[i]<=a[i-1]){ 16 printf("0\n"); 17 flag=1; break; 18 } 19 if(flag) continue;//1850改为return 0; 20 for(int i=1;i<len;++i) ans+=C[26][i];//长度<len 21 for(int i=0;i<len;++i){//长度==len,字典序排名在给定串前,枚举每一位 22 for(char ch=i?a[i-1]+1:'a';ch<a[i];++ch)//枚举每个小于a[i]的字母 23 ans+=C['z'-ch][len-i-1]; 24 }printf("%d\n",ans); 25 }return 0; 26 }