beautiful number
Problem Description
Let A=∑i~n=ai∗10n−i(1≤ai≤9)(n is the number of A’s digits). We call A as “beautiful number” if and only if a[i]≥a[i+1] when 1≤i<n and a[i] mod a[j]=0 when 1≤i≤n,i<j≤n(Such as 931 is a “beautiful number” while 87 isn’t).
Could you tell me the number of “beautiful number” in the interval [L,R](including L and R)?
Input
The fist line contains a single integer T(about 100), indicating the number of cases.
Each test case begins with two integers L,R(1≤L≤R≤109).
Output
For each case, output an integer means the number of “beautiful number”.
Sample Input
2
1 11
999999993 999999999
Sample Output
10
2
解题思路:
数位DP。
这题前导零是有影响的,所以必须记录前导零。
还有一个就是前一位的数字。
状态转移必须满足题目要求的两个点。
剩下的就是敲模板了。
AC代码:
#include <bits/stdc++.h>
#define int long long
const int N = 1e6+10;
using namespace std;
int a[20];
int dp[20][12];
int dfs(int pos,int pre,int limit,int lead)
{
if(pos == -1) return 1;
if(!limit && !lead && dp[pos][pre] != -1) return dp[pos][pre];
int up = limit ? a[pos] : 9;
int tmp = 0;
for(int i = 0 ; i <= up ; i ++)
{
if(lead)
tmp += dfs(pos-1,i,limit && a[pos] == i , lead && i == 0);
else
{
if(i == 0) continue;
if(i > pre ) break;
if(pre%i == 0)
tmp += dfs(pos-1,i,limit&&a[pos] == i,0);
}
}
if(!limit && !lead) dp[pos][pre] = tmp;
return tmp;
}
int res(int n)
{
int pos =0;
while(n)
{
a[pos++] = n%10;
n /=10;
}
return dfs(pos-1,0,1,1);
}
signed main()
{
int t;
cin>>t;
memset(dp,-1,sizeof(dp));
while(t--)
{
int a,b;
cin>>a>>b;
cout<<res(b) - res(a-1)<<endl;
}
return 0;
}