题目链接
题意:给定F(x)的公式,同时给定a和b,问你【0,b】区间内有多少数i满足F(i)<=F(a)
思路:标准的数位DP模板题,可以把F(a)先求出来,记忆化搜索的时候记录可行的状态(即pre),也就是pre-i*(1<<pos)大于0的时候pre状态时合法的,因为此时才说明F(a)比较大。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+1;
int dp[20][maxn],mx[20];
int f(int a)
{
int temp=1,ans=0;
while(a)
{
ans+=a%10*temp;
a/=10;
temp<<=1;
}
return ans;
}
int dfs(int pos,int pre,bool limit)
{
if(pos<0) return pre>=0;
if(pre<0) return 0;//不是可行状态
int up=limit?mx[pos]:9,ans=0;
if(!limit&&dp[pos][pre]!=-1) return dp[pos][pre];
for(int i=0;i<=up;++i)
{
ans+=dfs(pos-1,pre-i*(1<<pos),limit&&i==up);
}
if(!limit) dp[pos][pre]=ans;
return ans;
}
int solve(int a,int b)
{
int len=0;
while(b)
{
mx[len++]=b%10;
b/=10;
}
return dfs(len-1,f(a),true);
}
int main()
{
int T,a,b,j=0;
memset(dp,-1,sizeof(dp));
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&a,&b);
printf("Case #%d: %lld\n",++j,solve(a,b));
}
}