数字游戏
题目描述
科协里最近很流行数字游戏。某人命名了一种不降数,这种数字必须满足从左到右各位数字成小于等于的关系,如 123,446。现在大家决定玩一个游戏,指定一个整数闭区间([a,b]),问这个区间内有多少个不降数。
输入格式
有多组测试数据。每组只含两个数字(a,b),意义如题目描述。
输出格式
每行给出一个测试数据的答案,即([a,b])之间有多少不降数。
样例输入
1 9
1 19
样例输出
9
18
Hint
对于全部数据,(1leq a leq b leq 2^{31}-1)。
思路
数位dp,记录前一位的值即可
Code
/**********************************************************
* @Author: Kirito
* @Date: 2020-04-12 17:37:56
* @Last Modified by: Kirito
* @Last Modified time: 2020-04-12 17:47:00
* @Remark:
**********************************************************/
#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define CSE(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define Abs(x) (x>=0?x:(-x))
#define FAST ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll , ll> pll;
const int maxn=20;
ll dp[maxn][maxn], digit[maxn];
ll dfs(int pos, int state, bool limit, bool lead)
{
if(pos == -1) return 1;
if(!limit && !lead && dp[pos][state] != -1) return dp[pos][state];
int upbd = limit? digit[pos] : 9;
int ans = 0;
for (int i = state; i <= upbd; ++i)
{
ans += dfs(pos - 1, i, limit && i == upbd, lead && i == 0);
}
if(!limit && !lead) dp[pos][state] = ans;
return ans;
}
ll get_num(int x)
{
CSE(dp, -1);
int pos = 0;
while(x)
{
digit[pos++] = x % 10;
x /= 10;
}
return dfs(pos - 1, 0, true, true);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.in","r",stdin);
#endif
int x, y;
while(cin >> x >> y)
{
cout << get_num(y) - get_num(x - 1) << endl;
}
return 0;
}