【数位dp】HDU - 4734 F(x)
2018-03-06 20:16
344 查看
Problem Description
输入T组数据,每组数据输入A, B。
问你 0 到 B 的范围内有多少个数的f(x) <= f(A)。
f(123) = 1*2^2 + 2*2^1 + 3*2^0。
Sample Input
3
0 100
1 10
5 100
Sample Output
Case #1: 1
Case #2: 2
Case #3: 13
思路:
自己一开始的思路,求出f(A), dfs记忆化搜索的时候,边搜索边算,如果当前已经大于A就不继续搜索了。然后就超时了,因为这样的记忆化搜索跟A有关系,每组样例都得初始化,都得重新记忆化。
参考了一下别人的,求出f(A),边搜索边减小f(A),如果f(A) 减小至小于0 就返回。这样每组样例就不需要重新记忆化搜索了,就解决了超时问题。分别给出了TLE 和 AC代码
TLE代码
AC代码
输入T组数据,每组数据输入A, B。
问你 0 到 B 的范围内有多少个数的f(x) <= f(A)。
f(123) = 1*2^2 + 2*2^1 + 3*2^0。
Sample Input
3
0 100
1 10
5 100
Sample Output
Case #1: 1
Case #2: 2
Case #3: 13
思路:
自己一开始的思路,求出f(A), dfs记忆化搜索的时候,边搜索边算,如果当前已经大于A就不继续搜索了。然后就超时了,因为这样的记忆化搜索跟A有关系,每组样例都得初始化,都得重新记忆化。
参考了一下别人的,求出f(A),边搜索边减小f(A),如果f(A) 减小至小于0 就返回。这样每组样例就不需要重新记忆化搜索了,就解决了超时问题。分别给出了TLE 和 AC代码
TLE代码
#include<bits/stdc++.h> using namespace std; int A, B; int dp[15][5000], a[15]; int _pow(int x, int n) { int sum = 1; for(int i = 1; i <= n; i++) sum *= x; return sum; } int f(int x) { int sum = 0; for(int i = 0; x; i++) { sum += (x%10)*_pow(2, i); x = x/10; } return sum; } int dfs(int pos, int num, int limit) { if(pos < 0) return 1; if(!limit && dp[pos][num] != -1) return dp[pos][num]; int up = limit ? a[pos] : 9; int res = 0; for(int i = 0; i <= up; i++) { if(num + i*_pow(2, pos) > A) continue;//如果大于A就不继续搜索了,所以记忆化跟A有关,每次都需要初始化dp数组 res += dfs(pos-1, num+i*_pow(2,pos), limit && i == a[pos]); } if(!limit) return dp[pos][num] = res; return res; } int solve(int x) { int pos = 0; while(x) { a[pos++] = x%10; x = x/10; } return dfs(pos-1, 0, 1); } int main() { int T; scanf("%d", &T); for(int Case = 1; Case <= T; Case++) { memset(dp, -1, sizeof(dp)); scanf("%d %d", &A, &B); A = f(A); printf("Case #%d: %d\n", Case, solve(B)); } return 0; }
AC代码
#include<bits/stdc++.h> using namespace std; int A, B; int dp[15][5000], a[15]; int _pow(int x, int n) { int sum = 1; for(int i = 1; i <= n; i++) sum *= x; return sum; } int f(int x) { int sum = 0; for(int i = 0; x; i++) { sum += (x%10)*_pow(2, i); x = x/10; } return sum; } int dfs(int pos, int num, int limit) { if(num < 0) return 0;//当f(A) < 0的时候就不满足了,这样的记忆化 跟A没有关系 if(pos < 0) return 1; if(!limit && dp[pos][num] != -1) return dp[pos][num]; int up = limit ? a[pos] : 9; int res = 0; for(int i = 0; i <= up; i++) { res += dfs(pos-1, num - i*_pow(2, pos), limit && i == a[pos]); } if(!limit) return dp[pos][num] = res; return res; } int solve(int x) { int pos = 0; while(x) { a[pos++] = x%10; x = x/10; } return dfs(pos-1, A, 1);//搜索的时候传入的是f(A) } int main() { int T; scanf("%d", &T); memset(dp, -1, sizeof(dp)); for(int Case = 1; Case <= T; Case++) { scanf("%d %d", &A, &B); A = f(A); printf("Case #%d: %d\n", Case, solve(B)); } return 0; }
相关文章推荐
- HDU 4734 F(x)(数位DP)
- HDU 4734 F(x) (数位DP)
- Hdu 4734 【数位DP】.cpp
- F(x) HDU - 4734 (数位dp)
- HDU 4734 数位DP
- hdu 4734 F(x)(数位DP)
- HDU 4734 F(x) (数位DP)
- hdu 4734 数位dp
- hdu 4734 F(x) 数位dp
- HDU 4734 F(x) 数位DP
- HDU 4734 F(x)(数位DP)
- HDU 4734 (数位DP)
- hdu 4734(数位dp)
- HDU 4734: F(x) (数位DP)
- HDU 4734 F(x) 数位 dp
- HDU 4734 数位DP
- HDU 4734(数位dp)
- hdu 4734 F(x) --- 数位dp
- HDU 4734 F(x) 数位dp
- HDU 4734 F(x)(数位dp)