题意:定义 F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1(其中 x = AnAn-1An-2 ... A2A1),那么给定A,B,求[0,B]区间的i,满足F(i)<=F(A);
dp[pos][sum]表示跑到当前位,还剩sum值没用完时的答案。sum<0的时候一定不能忘记判断啊。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int t,k,wei[11],p[11];
ll A,B,dp[10][4620];
ll dfs(int pos,int sum,int limit)
{
if(pos<1) return sum>=0;
if(sum<0)return 0;///尤为重要,不然会wa
if(!limit&&dp[pos][sum]!=-1)
return dp[pos][sum];
int up=limit?wei[pos]:9;
ll ans=0;
for(int i=0;i<=up;i++)
{
ans+=dfs(pos-1,sum-i*p[pos],limit&&i==up);
}
if(!limit) dp[pos][sum]=ans;
return ans;
}
ll solve(ll x)
{
if(x<0) return 0;
if(x==0) return 1;
int len=0;
while(x)
{
wei[++len]=x%10;
x/=10;
}
ll ans=0;
ans+=dfs(len,k,1);
return ans;
}
int fuck(ll x)
{
int ans=0,tmp=1;
while(x)
{
ans+=x%10*tmp;
x/=10;
tmp*=2;
}
return ans;
}
int main()
{
scanf("%d",&t);
p[1]=1;
for(int i=2;i<=10;i++)
p[i]=p[i-1]*2;
int cas=0;
memset(dp,-1,sizeof dp);
while(t--)
{
scanf("%lld%lld",&A,&B);
k=fuck(A);
ll ans=solve(B);
printf("Case #%d: %lld\n",++cas,ans);
}
return 0;
}