HDU4734 F(x)(数位DP)

xiaoxiao2021-02-28  109

F(x)

Time Limit: 1000/500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5850    Accepted Submission(s): 2208 Problem Description 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).   Input The first line has a number T (T <= 10000) , indicating the number of test cases. For each test case, there are two numbers A and B (0 <= A,B < 10 9)   Output For every case,you should output "Case #t: " at first, without quotes. The  t is the case number starting from 1. Then output the answer.   Sample Input 3 0 100 1 10 5 100   Sample Output Case #1: 1 Case #2: 2 Case #3: 13   Source 2013 ACM/ICPC Asia Regional Chengdu Online

题意:

  我们定义十进制数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,求出0~b有多少个不大于f(a)的数。

分析:

dp[i][j]表示i位值<=j 的总数

#include<bits/stdc++.h> using namespace std; int dp[20][200000], bit[20]; int A, B; 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 lim = flag ? bit[pos] : 9; for(int i = 0; i <= lim; i++) ans += dfs(pos-1, num-i*(1<<pos), flag&&i==lim); if(!flag) dp[pos][num] = ans; return ans; } int F(int x) { int ret = 0, len = 0; while(x) { ret += (x)*(1<<len); len++; x /= 10; } return ret; } int calc() { int len = 0; while(B) { bit[len++] = B % 10; B /= 10; } return dfs(len-1, F(A), true); } int main() { int t; scanf("%d", &t); memset(dp, -1, sizeof(dp)); for(int kase = 1; kase <= t; kase++) { scanf("%d%d", &A, &B); printf("Case #%d: %d\n", kase, calc()); } return 0; }

转载请注明原文地址: https://www.6miu.com/read-18644.html

最新回复(0)