【poj1850】 Code 数位dp+记忆化搜索

题目大意:给你一个字符串,问你这个字符串的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 }
原文地址:https://www.cnblogs.com/xiefengze1/p/7744670.html