题目大意:给你一个字符串,问你这个字符串的rank,如果这个字符串不合法,请直接输出0。(一个合法的字符串是对于∀i,有c[i]<c[i+1])
字符串s的rank的计算方式:以字符串长度作为第一关键字,字符串大小作为第二关键字,将该字符串集排序,若从小到达数到的第k个字符串为s,则s的rank为k。
此题由于数据范围非常小(strlen(c)≤10),感觉暴力应该是可以AC的,不过我还是打了个数位dp。
此题直接记忆化搜索统计答案即可。不过要注意输入一个字符串时判断该字符串是否在该字符集内(我就未判这个结果翻车了....)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define M 10 5 #define L long long 6 using namespace std; 7 L f[M][30]={0}; 8 char c[M]={0}; int num[M]={0}; 9 L dfs(int n,int m,int op){ 10 if(!op&&f[n][m]!=-1) return f[n][m]; 11 if(n==0) return 1; 12 if(!op){ 13 f[n][m]=0; 14 for(int i=m+1;i<=26;i++) f[n][m]+=dfs(n-1,i,op); 15 return f[n][m]; 16 }else{ 17 L sum=0; 18 for(int i=m+1;i<num[n];i++) sum+=dfs(n-1,i,0); 19 return sum+dfs(n-1,num[n],op); 20 } 21 } 22 int main(){ 23 scanf("%s",c+1); 24 int n=strlen(c+1); 25 for(int i=1;i<=n;i++){ 26 num[i]=c[n-i+1]-'a'+1; 27 if(c[i-1]>=c[i]) {printf("0 "); return 0;} 28 } 29 memset(f,-1,sizeof(f)); 30 L sum=0; 31 for(int nn=1;nn<n;nn++){ 32 for(int i=1;i<=26;i++) 33 sum+=dfs(nn-1,i,0); 34 } 35 for(int i=1;i<num[n];i++) 36 sum+=dfs(n-1,i,0); 37 sum+=dfs(n-1,num[n],1); 38 printf("%lld ",sum); 39 }