题意:定义 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 ] [ k ]为当前考虑pos位,之后(pos + 1)位与之前的位数组合形成的F函数值不超过k的数的个数,详见代码:
/*********************************************************
file name: hdu4734.cpp
author : kereo
create time: 2015年01月20日 星期二 11时09分03秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=10;
const int MAXN=6000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=100000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int res;
int bit[N],dp[N][MAXN],a[N],p[N];
int dfs(int pos,int st,int flag){
if(pos == -1) return 1;
if(flag && dp[pos][st]!=-1)
return dp[pos][st];
int ans=0;
int x=flag ? 9 : bit[pos];
for(int i=0;i<=x;i++){
int k=st-(int)p[pos]*i;
if(k<0)
continue;
ans+=dfs(pos-1,k,flag || i<x);
}
if(flag)
dp[pos][st]=ans;
return ans;
}
int solve(int x){
int len=0;
do{
bit[len++]=x%10;
x/=10;
}while(x);
return dfs(len-1,res,0);
}
int main(){
int T,kase=0;
scanf("%d",&T);
p[0]=1;
for(int i=1;i<10;i++)
p[i]=p[i-1]*2;
memset(dp,-1,sizeof(dp));
while(T--){
int A,n;
scanf("%d%d",&A,&n);
int cnt=0; res=0;
do{
a[cnt++]=A%10;
A/=10;
res+=p[cnt-1]*a[cnt-1];
}while(A);
int ans=solve(n);
printf("Case #%d: %d\n",++kase,ans);
}
return 0;
}