HDU 3555 Bomb (数位dp)
2015-09-05 20:20
323 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3555
题意:求出1到N (1 <= N <= 2^63-1)的数中,包含“49”的数的个数。
思路:用数位dp的记忆化搜索模版。
代码:
题意:求出1到N (1 <= N <= 2^63-1)的数中,包含“49”的数的个数。
思路:用数位dp的记忆化搜索模版。
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 1000000007 #define INF 0x7fffffff using namespace std; typedef long long ll; int bit[70]; ll f[70][5]; ll dp(int pos, int sta, int flag) { //第len到pos+1位的数字已确定,现在要确定第pos位 //sta=0则前面确定的序列不含49,sta=1则第pos-1位为4,sta=2则前面确定的序列包含49 //flag=1,不论该位为多少都比N小 if(pos == 0) return sta == 2; if(flag && f[pos][sta] != -1) return f[pos][sta]; int x = flag ? 9 : bit[pos]; ll ans = 0; for(int i = 0; i <= x; i++) { if(sta == 2 || (sta == 1 && i == 9)) { ans += dp(pos - 1, 2, flag || i < x); } else if(i == 4) { ans += dp(pos - 1, 1, flag || i < x); } else { ans += dp(pos - 1, 0, flag || i < x); } } if(flag) f[pos][sta] = ans; return ans; } ll cal(ll n) { int len = 0; while(n) { bit[++len] = n % 10; n /= 10; } ll ans = dp(len, 0, 0); return ans; } int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif int t; ll n; scanf("%d", &t); memset(f, -1, sizeof(f)); while(t--) { scanf("%I64d\n", &n); printf("%I64d\n", cal(n)); } return 0; }
相关文章推荐
- 笔试基础(第二篇
- 排序算法之Java实现3——直接插入排序算法
- 生活
- nginx实现图片防盗链(referer指令)
- 使用Ajax long polling实现简单的聊天程序
- C++继承实例
- PHP常量官方文档解释
- DOM
- hdu1069
- Twitter 帐号申请解封
- 排序算法之Java实现2——堆排序算法
- PMP杂谈--项目日历,资源日历,自然日历,资源直方图
- Linux常见问题解答--如何修复“tar:Exiting with failure status due to previous errors”
- 如何利用一个数据库中间件扩展MySQL集群——kingshard使用指南
- Hadoop 案例7-----日志分析:分析非结构化文件
- Cocos2d-x v3.6制作射箭游戏(一)
- 关键路径求解
- 求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)
- Ajax学习之可编辑表格
- 【C++】实现STL模板类string