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\n",iCase,calc(A,B)); } return 0; }