题目链接:https://vjudge.net/problem/FZU-2109
题目大意
假设x=a[0]a[1]...a[len-2]a[len-1],x>0,并且a[2i+1]>=a[2i],a[2i+1]>=a[2i+2]。
分析
dp[i][j][k]表示还剩多少位,前一位是什么,是不是奇数位(从左到右)的最优解。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
int dp[20][15][2];//长度,前一位是什么,是否为奇数位
int digit[20];
int dfs(int len, int pre, int odd, int lead, int limit)
{
if(len < 0) return 1;
if(!limit && dp[len][pre][odd] != -1) return dp[len][pre][odd];
int up = limit ? digit[len] : 9;
int ans = 0;
for(int i = 0; i <= up; i++)
{
if(!(lead || i))
ans += dfs(len - 1, 9, 0, 0, limit && i == up);
else if(odd && pre <= i)
ans += dfs(len - 1, i, !odd, 1, limit && i == up);
else if(!odd && pre >= i)
ans += dfs(len - 1, i, !odd, 1, limit && i == up);
}
if(!limit) dp[len][pre][odd] = ans;
return ans;
}
int solve(int n)
{
int k = 0;
while(n)
{
digit[k++] = n % 10;
n /= 10;
}
return dfs(k - 1, 9, 0, 0, 1);
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int a, b;
memset(dp, -1, sizeof dp);
scanf("%d %d", &a, &b);
printf("%d\n", solve(b) - solve(a - 1));
}
return 0;
}