hdu 4734 F(x) 数位DP裸
2017-10-02 21:53
92 查看
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
30 100
1 10
5 100
Sample Output
Case #1: 1Case #2: 2
Case #3: 13
这道题是说要求在0到B里有多少个数的F值小于等于F(A),然后我们可以发现这题可以数位DP做,F值的定义是一个数的这一位乘以这一位的2次方
举个例子
1234 = 4 * 1 + 3 * 2 + 2 * 4 + 1 * 8
借这道题写一下数位DP的模板的套路
dfs函数里面传参
dfs( int len, int ... ,int lead, int limit )
有些题会有其他参数,有些题需要传lead,表示是否有前导0,limit通常表示这一位有没有限制,如果有限制的话就应该是这一位的上限,如果没有限制的话就是0-9
在函数里面我们通常是先设计返回的情况,比如len为-1的时候返回这个点是否满足,满足为1,不满足为0,再比如我们记忆化一个dp[i][j],当这个点没有limit限制并且没有前导零限制等各种限制时return这个dp[i][j],否则我们就求一个这一位的up值,表示这一位最大可以取什么,然后for语句取for一些状态然后继续dfs下去,最后在没有限制的情况下把答案赋值给dp数组,也就是记忆化数组里面,最后再return即可,通常我们会在solve函数里面先把数位分解为我们想要的样子放到数组里面,十进制分解,二进制分解等等,放到数组里面,记录长度然后再传入dfs函数中,最后计算得出答案返回到主函数中
这道题其实就是一道裸题,按照上面说的思路来就可以了
#include <bits/stdc++.h> using namespace std; int len, dp[11][ 50000 + 10 ], a[25]; int F( int n ) { int tmp = 0, BASE = 1; while( n ) { tmp += n % 10 * BASE; BASE *= 2; n /= 10; } return tmp; } int dfs( int pos, int ans, int flag ) { if( pos < 0 ) return ans >= 0; if( ans < 0 ) return 0; int sum = 0; if( !flag && dp[pos][ans] != -1 ) return dp[pos][ans]; int up = flag ? a[pos] : 9; for( register int i = 0; i <= up; i++ ) sum += dfs( pos - 1, ans - i * ( 1 << pos ), flag && i == up ); if( !flag ) dp[pos][ans] = sum; return sum; } int solve( int A, int B ) { len = 0; while(B) { a[len++] = B % 10; B /= 10; } return dfs( len - 1, F(A), 1 ); } int main( ) { int T, A, B; scanf( "%d", &T ); memset( dp, -1, sizeof(dp) ); for( register int Emmmm = 1; Emmmm <= T; Emmmm++ ) { scanf( "%d%d", &A, &B ); printf("Case #%d: %d\n", Emmmm, solve( A, B ) ); } return 0; }
相关文章推荐
- HDU 4734 F(x) ★(数位DP)
- HDU-4734 F(x) (数位DP)
- [数位dp] hdu 4734 F(x)
- HDU 4734 (数位DP)
- hdu 4734 数位DP
- HDU - 4734 F(x) (2013成都网络赛,数位DP)
- HDU 4734 F(x) ★(数位DP)
- HDU 4734 F(x) (数位DP)
- HDU 4734 F(x)【数位DP】
- HDU 4734 F(x)(数位dp)
- hdu 4734 F(x) --- 数位dp
- HDU 4734 数位DP
- 【数位dp】HDU - 4734 F(x)
- HDU 4734 数位DP 解题报告
- HDU 4734 F(x)(数位dp)
- hdu 4734 F(x) 数位dp
- hdu 4734 F(x)(数位dp)
- hdu 4734 F(x) 数位dp 基础 2013 成都网络赛
- HDU 4734 F(x) 数位dp
- HDU 4734 F(x) (数位dp)