poj 1496
这个题目的意思是给你一串没有重复且递增的只包含a-z的字符串, 让你求出这个字符串排在第几位。 经过思考我们可以得出长度为n的字符串的个数为C(26, m), 然后我们要统计长度和给定的字符串相同但是字典序小于给定的字符串的个数。 对于一个序列a1a2...an来说, 我们逐个位置统计, 设xi为从恰好从第i位开始变小的方案数,第i位可以填的数在a[i-1]到a[i]之间, 假设我们填了k, (a[i-1]<k<a[i]) 那么后面n-i位就有C[z-k][n-i]个。 枚举i和k即可, 另外我们可以打表计算c(n, m)原理如下:c(i, j) = (i-j+1)*c(i, j-1)/j.代码如下:
#include <cstdio> #include <algorithm> #include <cstring> using namespace std; int c[30][30]; char in[15]; bool judge(char a[], int len) { for(int i=1; i<len; i++) if(a[i]<a[i-1]) return true; for(int i=0; i<len; i++) for(int j=0; j<i-1; j++) if(a[i]==a[j]) return true; return false; } int main() { for(int i=1; i<=27; i++) { c[i][0] = 1; for(int j=1; j<=i; j++) c[i][j] = (i-j+1)*c[i][j-1]/j; } while(scanf("%s", in+1) == 1) { in[0] = 96; int len = strlen(in+1); if(judge(in+1, len)) { printf("0\n"); } else { int res = 0; for(int i=1; i<=len-1; i++) res += c[26][i]; for(int i=1; i<=len; i++) { for(int j=in[i]-'a'+1-1; j>in[i-1]-'a'+1; j--) res += c[26-j][len-i]; } printf("%d\n", res+1); } } //printf("%d", 'a'-1); return 0; }