首页 > 代码库 > hdu 4734 F(x)(数位dp+优化)
hdu 4734 F(x)(数位dp+优化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4734
题意:我们定义十进制数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
dp[len][count]表示前len位权值为count的有多少,然后显然的在len==0时return count>=f(a);
但是这样每次Gets数字时都要初始化一下dp然而这题刚好时间要求时500ms而且组数比较多,那么
这样肯定要超时,count经过计算最大只有4599所以设为4600也可以但这样也要超时,于是要优化
一下dp。依旧是dp[len][count]但这时count表示的是钱len位权值不超过count的数有几个,那么只
要一开始初始化一下dp就可以了。
#include <iostream>#include <cstdio>#include <cmath>#include <cstring>using namespace std;const int M = 4600;int dp[10][M] , dig[10] , fat;int dfs(int len , int Fx , int flag , int power) { if(!len) return Fx >= 0; if(Fx < 0) return 0; if(!flag && dp[len][Fx] != -1) return dp[len][Fx]; int t = flag ? dig[len] : 9; int sum = 0; for(int i = 0 ; i <= t ; i++) { sum += dfs(len - 1 , Fx - power * i , flag && i == t , power / 2); } if(!flag) dp[len][Fx] = sum; return sum;}int Get(int x) { int sum = 0; int len = 0; if(x == 0) { return 0; } int power = 1; while(x) { sum += power * (x % 10); x /= 10; power *= 2; } return sum;}int Gets(int x) { int len = 0; if(x == 0) { dig[++len] = 0; } int power = 1; while(x) { dig[++len] = x % 10; x /= 10; power *= 2; } return dfs(len , fat , 1 , power / 2);}int main() { int t; int ans = 0; memset(dp , -1 , sizeof(dp)); scanf("%d" , &t); while(t--) { ans++; int a , b; scanf("%d%d" , &a , &b); fat = Get(a); printf("Case #%d: %d\n" , ans , Gets(b)); } return 0;}
hdu 4734 F(x)(数位dp+优化)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。