题意:
给出一个严格按字典序升序的字符串(否则非法)每个字符串都比它前一个字符串的对应数字大1。给任意字符串判断是否合法后输出对应的数值。
思路:
虽然被归类到poj组合数学里,但是我只有隐隐约约模糊的感觉。直接做做不出来,羞愧。还是看了人家的题解才懂的。对,就是我自己没有清晰的思路。。。。。。
其实是在保证严格升序的情况下,比如某个字符串我已经选过a了,那接下来只能在剩下的25个字母中选,C (25 ,1)类似这样转化成用组合数算,然后处理一些细节。
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
typedef long long LL;
int c[27][27];
char s[30];
void table()
{
for(int i=0;i<=26;i++)
for(int j=0;j<=26;j++)
if(!j || i==j) c[i][j]=1;
else c[i][j]=c[i-1][j-1]+c[i-1][j];
c[0][0]=0;
}
int main()
{
table();
scanf("%s",s);
int len=strlen(s);
for(int i=1;i<len;i++)
if(s[i-1]>=s[i]){cout<<0<<endl; return 0;}
int sum=0;
for(int i=1;i<len;i++)
sum+=c[26][i]; //c[26][i]表示 长度为i的字符串的个数
for(int i=0;i<len;i++)//处理长度为len的字符串,从头到尾组合
{
//类似于从第一个字符到最后一个字符一层层加起来,一层层,用心感受
char ch=(!i)?'a':s[i-1]+1;
while(ch<=s[i]-1)
{
sum+=c['z'-ch][len-1-i];
ch++;
}
}
cout<<++sum<<endl;
return 0;
}