题目链接:https://vjudge.net/problem/POJ-1850
这题我用的是数位dp,刚刚看了一下别人用排列组合,我脑子不行,想不出来。
在这题里面我把a看成1,其他的依次递增,如果这一位是0则说明没有字符,每次搜索到第pos位,那么这一位的数字有两种情况,一种是这一位的i比前一位pre大,则从i继续搜索,另一种是前一位是0,没有字符,那么这一位就可以取任何值(但是要注意避免全部为0的情况),然后用数位dp模板套了一下。
代码:
#include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<map> #include<stack> #include<cmath> #include<vector> using namespace std; #define eps 1e-8 #define ll long long #define INF 1e9 ll dp[15][30]; int digit[15]; char str[15]; ll dfs(int pos,int pre,int limit) { if(pos==0) return 1; if(!limit&&dp[pos][pre]!=-1) return dp[pos][pre]; int num=limit?digit[pos]:26; ll sum=0; for(int i=0;i<=num;i++) { if(i>pre||pre==0&&pos!=1)//这里pre==0是那种前面没字符的情况,加了pos!=1是防止全部都是0的情况 { sum+=dfs(pos-1,i,i==num&&limit); } } if(!limit&&dp[pos][pre]==-1) dp[pos][pre]=sum; return sum; } ll cal() { memset(dp,-1,sizeof(dp)); int len=strlen(str); int cnt=0; for(int i=len-1;i>=0;i--)//把字符转化为数字 { digit[++cnt]=str[i]-'a'+1; } int flag=0; for(int i=len-1;i>=1;i--)//判断是否升序 { if(digit[i]<=digit[i+1]) { flag=1; break; } } if(flag) return 0; return dfs(len,0,1); } int main() { cin>>str; cout<<cal()<<endl; return 0; }