For a decimal number x with n digits (A nA n-1A n-2 ... A 2A 1), we define its weight as F(x) = A n * 2 n-1 + A n-1 * 2 n-2 + ... +
A 2 * 2 + A 1 * 1. Now you are given two numbers A and B, please calculate how many numbers are there between 0 and B, inclusive, whose weight is no more than F(A).
For each test case, there are two numbers A and B (0 <= A,B < 10 9)
3 0 100 1 10 5 100
Case #1: 1 Case #2: 2 Case #3: 13
题意:
我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字。
题目给出a,b,求出有多少个F(i)(0<=i<=b)不大于f(a)的数。
基础的数位DP题目
#include <bits/stdc++.h>
using namespace std;
int dp[20][10000]; ///dp[i][j]是i位置之前的和小于sum的个数
int bit[20];
int dfs(int pos,int num,bool flag)
{
if(pos == -1)return num >= 0; ///出口
if(num < 0)return 0; ///剪枝
if(!flag && dp[pos][num] != -1)
return dp[pos][num];
int ans = 0;
int end = flag?bit[pos]:9;
for(int i = 0;i <= end;i++)
ans += dfs(pos-1,num - i*(1<<pos),flag && i==end);
if(!flag) dp[pos][num] = ans;
return ans;
}
int F(int x)
{
int ret = 0;
int len = 0;
while(x)
{
ret += (x%10)*(1<<len);
len++;
x /= 10;
}
return ret;
}
int calc(int A,int B)
{
int len = 0;
while(B)
{
bit[len++] = B%10;
B/=10;
}
return dfs(len-1,F(A),1);
}
int main()
{
int T,A,B;
int iCase = 0;
scanf("%d",&T);
memset(dp,-1,sizeof(dp));
while(T--)
{
iCase++;
scanf("%d%d",&A,&B);
printf("Case #%d: %d
",iCase,calc(A,B));
}
return 0;
}