题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6148
题意:如题。
解法:裸数位DP,dp[pos][pre][sta]表示当前在pos位,前一位的数字是pre,当前状态是上升还是下降的合法的数的个数。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 110;
const int mod = 1e9+7;
LL dp[maxn][12][2];
LL digit[maxn];
LL dfs(int pos, int sta, int pre, int lim)
{
if(pos<1) return 1;
if(!lim&&~dp[pos][pre][sta]) return dp[pos][pre][sta];
int jud = lim?digit[pos]:9;
LL ans = 0;
if(sta){
for(int i=pre; i<=jud; i++){
ans += dfs(pos-1, 1, i, lim&&i==jud);
ans %= mod;
}
}else{
for(int i=0; i<=jud; i++){
if(i>pre){
ans += dfs(pos-1,1,i,lim&&i==jud);
ans %= mod;
}
else{
if(!i&&pre==10)
ans += dfs(pos-1,0,10,lim&&i==jud);
else
ans += dfs(pos-1,0,i,lim&&i==jud);
ans %= mod;
}
}
}
if(!lim) dp[pos][pre][sta] = ans;
return ans;
}
LL f(char s[])
{
int len = strlen(s);
for(int i=0; i<len; i++){
digit[len-i] = s[i]-'0';
}
return dfs(len, 0, 10, 1);
}
char s[110];
int main()
{
memset(dp, -1, sizeof(dp));
int T;
scanf("%d", &T);
while(T--)
{
scanf("%s", s);
printf("%lld\n", (f(s)-1+mod)%mod);
}
return 0;
}