[数位DP] HDU4734 F(x)
来源:互联网 发布:sqlserver enterprise 编辑:程序博客网 时间:2024/06/05 06:44
HDU4734
题意:设整数x的十进制表示为An*10^n-1 + An-1*10^n-2 ... A1*10^0, 定义函数F(x)=An*2^n-1 + An-1*2^n-2 +...+A1*10^0,然后对任意x∈[0, B]求F(x)值不超过F(A)的x的个数。
解法:数位DP。 DP[i][j]表示1~i位的数中F函数值不超过j的数的个数,DP[len][F(A)]即为答案。
技巧:从F(A)往0搜,如果从0往F(A)搜的话,对不同F(A),DP需要记忆的信息是不同的,每次都重新跑DP会超时。
#include<bits/stdc++.h>#define ll long long intusing namespace std;int f(ll x){ ll res = 0, b = 1; while(x){ res += (x%10)*b; x /= 10; b *= 2; } return res;}int dp[15][6000], p2[15];int num[15];int dfs(int pos, int sum, int f){ if(sum < 0) return 0; if(pos < 1) return sum >= 0; if(!f && dp[pos][sum] != -1) return dp[pos][sum]; int end = f? num[pos] : 9; int res = 0; for(int i = 0; i <= end; ++i){ res += dfs(pos-1, sum-i*p2[pos], f && i == end); } if(!f) dp[pos][sum] = res; return res;}int solve(int a, int b){ int len = 0; while(b){ num[++len] = b%10; b /= 10; } return dfs(len, f(a), 1);}void init(){ p2[1] = 1; for(int i = 2; i <= 10; ++i) p2[i] = p2[i-1]*2; memset(dp, -1, sizeof(dp));}int main(){ init(); int T, ca = 1; scanf("%d", &T); while(T--){ int a, b; scanf("%d%d", &a, &b); printf("Case #%d: %d\n", ca++, solve(a, b)); }}
0 0
- hdu4734,F(x), 数位dp
- hdu4734 F(x) 数位dp
- HDU4734 F(x) 数位DP
- hdu4734---F(x)(数位dp)
- hdu4734 F(x) 数位dp
- HDU4734 F(x) 数位DP
- [数位DP] HDU4734 F(x)
- hdu4734 F(x) (数位dp)
- 【HDU4734】F(x) 数位DP
- HDU4734 F(x)[数位DP]
- HDU4734 F(x) 数位dp
- hdu4734 F(x) 数位dp
- F(x) (数位DP hdu4734)
- hdu4734 F(x)(数位dp)
- HDU4734 F(x) (数位DP)
- hdu4734 F(x)(数位dp)
- hdu4734——F(x) (数位DP)
- HDU4734 F(x)(数位DP)
- 解决Chrome插件安装时出现的“程序包无效”问题
- NSRULConnection网络应用
- 打造自己的vim
- 笔记:继承设计的技巧
- C#连接数据库代码(基础)
- [数位DP] HDU4734 F(x)
- 结构体指针之 段错误 详解(segmentation fault)
- Hbase存储数据结构
- 指针和数组的不同
- 网络-NSURLSession应用和原理
- 位运算:二进制中1的个数
- 字符串匹配
- Android面试题搜集
- 魔道研究