数位DP入门之hdu 3555 Bomb
2016-01-29 09:34
656 查看
数位DP入门之hdu 3555 Bomb
题意:
在1~N(1<=N<=2^63-1)范围内找出含有 ‘49’的数的个数;
与hdu 2089 不要62的区别:2089是找不不含 ‘4’和 ‘62’的区间范围内的数,此题是含有;正好相反,对于 “不要62”只是用第二位表示首位数字,这一题呢?
看转化:易知一定要要知道首位是9的个数,才能在前面加4得到 ‘49’,但是什么状态能从不含 ‘49’转移到含 ‘49’?直接在不含‘49’前加9,那么就出现了三个状态之间的递推转化,从而推出了第二维要使用三个状态来得出长度为i时的所有情况;
二维的状态:
[0]:只是不含 ‘49’,不管首位(可以是9); [1]:不含 ‘49’,但首位是9; [2]:含有 ‘49’
code:
题意:
在1~N(1<=N<=2^63-1)范围内找出含有 ‘49’的数的个数;
与hdu 2089 不要62的区别:2089是找不不含 ‘4’和 ‘62’的区间范围内的数,此题是含有;正好相反,对于 “不要62”只是用第二位表示首位数字,这一题呢?
看转化:易知一定要要知道首位是9的个数,才能在前面加4得到 ‘49’,但是什么状态能从不含 ‘49’转移到含 ‘49’?直接在不含‘49’前加9,那么就出现了三个状态之间的递推转化,从而推出了第二维要使用三个状态来得出长度为i时的所有情况;
二维的状态:
[0]:只是不含 ‘49’,不管首位(可以是9); [1]:不含 ‘49’,但首位是9; [2]:含有 ‘49’
code:
[code]#include<bits/stdc++.h> using namespace std; #define rep(i,n) for(i = 0;i < (n);i++) typedef long long ll; ll f[25][3]; void init() { f[0][0] = 1; for(int i = 1;i <= 20;i++){ f[i][0] = f[i-1][0] * 10 - f[i-1][1]; f[i][1] = f[i-1][0]; // start with 9 f[i][2] = f[i-1][1] + f[i-1][2]*10; // contian 49 } } ll query(ll n) { int d[25]={},tot = 0; while(n){ d[++tot] = n % 10; n /= 10; } ll ans = 0,flag = 1; for(int i = tot;i > 0;i--){ ans += f[i-1][2]*d[i]; if(flag && d[i] > 4) ans += f[i-1][1]; if(!flag) ans += f[i-1][0]*d[i]; if(d[i+1] == 4 && d[i] == 9) flag = 0; } return ans; } int main() { init(); int T; cin>>T; while(T--){ ll n; scanf("%I64d",&n); printf("%I64d\n",query(n+1)); } }
相关文章推荐
- 将Eclipse代码导入到AndroidStudio的两种方式
- Remote Displayer for Android V1.2
- 0129 ---稳定定的 plist介绍
- JAVA开发:深入研究java.lang.Class类
- iOS :获取通讯录 新的contact框架
- Ubuntu环境下OpenGrok的安装及使用
- jqgrid not allow select all
- 自定义图表控件--同时显示柱状图和折线图
- 透过浏览器看HTTP缓存
- P2P可以用UDP实现,而UDP在NAT打洞上面更加方便和成熟
- 1、Spring Boot简介
- Android控件的隐藏与显示
- LeetCode Reverse Linked List
- 【代码笔记】对iphone手机进行判断的一些函数
- Linux下配置SSL
- 第一章 线程安全性
- Linux下安装、配置、启动Apache
- 204_矩阵乘幂多项式 Matrix power series (POJ 3233)
- 【代码笔记】对iphone手机进行判断的一些函数
- cocos2d-x系列教程