数位dp,state标志前面若干位是否存在递增序列。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll ; const int max_n=105; const int mod = 1000000007; ll n; ll dp[max_n][13][2], a[max_n]; string s; ll dfs(int pos,int pre,int limit,int state) { if(pos == -1) return 1; if(!limit && dp[pos][pre][state] != -1) return dp[pos][pre][state]; ll tmp = 0; int up = limit?a[pos]:9; for(int i = 0; i <= up; i++) { if(pre==11 && i==0){ //注意处理前导0的情况,全0的情况下要填入一个不影响结果的数字 tmp = (tmp + dfs(pos-1, 11, limit&&i==up, 0))%mod; continue; } if(i<pre && state) continue; if(i<=pre) tmp = (tmp + dfs(pos-1, i, limit&&i==up, state))%mod; else tmp = (tmp + dfs(pos-1, i, limit&&i==up, 1))%mod; } if(!limit) dp[pos][pre][state] = tmp; return tmp; } ll solve() { int pos = 0; for(int i = s.length()-1; i>=0; i--) { a[pos++] = (s[i]-'0'); } return dfs(pos-1,11,1,0); } int main() { int T; scanf("%d",&T); memset(dp, -1, sizeof(dp)); while(T--) { cin>>s; printf("%I64d\n",solve()-1); } return 0; }