HDU 3555 Bomb + HDU 2089 不要62 数位dp入门题目
来源:互联网 发布:天津统计局人口数据 编辑:程序博客网 时间:2024/05/22 09:50
第一次接触数位dp的问题,在这里记录一下我个人的学习思路,如果能够对大家有什么帮助那就是最好的了。
动态规划也是刚刚开始学习,说实话对这种类型的题目现在还没有太适应。。。
数位dp通常都是类似这种叙述的问题:给定区间[l , m],求解其中满足(不满足)条件 p 的解集大小。
初始化的时候会开一个数组dp[n][10],dp[i][j] 表示第 i 位上为数字 j 并且符合(不符合)条件 p 的数目。一般用一个三重循环来搞定初始化的数值:
(pseudo code is as follow)
dp[0][0] = 1;for (int i = 1; i < n; i++){for (int j = 0; j < 10; j++){for (int k = 0; k < 10; k++){if (p){dp[i][j] += dp[i - 1][k];}}}}
第一重循环是n - 1位数位完全遍历,第二重和第三重循环分别是第 i 位和第 i - 1 位数位上0~9的数值。
dp[i][j] = dp[i][j] + dp[i - 1][k] 的含义是,当前位解集的大小为满足当前条件的数目和上一位解集大小之和(将这个过程联想成一棵树形的迭代结构)。接下来的过程就是根据题目具体描述来进行分析了。
HDU-2089 不要62 问题概述:给定数值范围n,m;求其中不是不吉利的数有多少个(不含4并且不含62)
AC代码如下
#include<iostream>using namespace std;//#include<cmath>//#include<string>long long dp[10][10];void init(){dp[0][0] = 1;for (int i = 1; i < 10; i++){for (int j = 0; j < 10; j++){for (int k = 0; k < 10; k++){if (j != 4 && !(j == 6 && k == 2)){dp[i][j] += dp[i - 1][k];}}}}}long long solution(long long n){int digit[15];int len = 0;long long mem = n, ans = 0;while (n > 0){digit[++len] = n % 10;n /= 10;}digit[len + 1] = 0;for (int i = len; i > 0; i--){for (int j = 0; j < digit[i]; j++){if (!(digit[i+1] == 6 && j == 2) && j != 4){ans += dp[i][j];}}if ((digit[i] == 2 && digit[i + 1] == 6) || digit[i] == 4){break;}}return ans;}int main(){init();long long n, m;while (cin >> n >> m){if (n == 0 && m == 0){break;}cout << solution(m + 1) - solution(n)<< endl;}//system("pause");return 0;}
相邻两位进行判断即可
HDU-3555 Bomb 问题概述:输入最大倒计时数n,求炸弹能量增加的最大值(求小于n并且含49的数字有多少个)
#include<iostream>using namespace std;//#include<cmath>//#include<string>long long dp[20][10];void init(){dp[0][0] = 1;for (int i = 1; i < 20; i++){for (int j = 0; j < 10; j++){for (int k = 0; k < 10; k++){if (!(j == 4 && k == 9)){dp[i][j] += dp[i - 1][k];}}}}}long long solution(long long n){int digit[20];int len = 0;long long mem = n, ans = 0;while (n > 0){digit[++len] = n % 10;n /= 10;}digit[len + 1] = 0;for (int i = len; i > 0; i--){for (int j = 0; j < digit[i]; j++){if (!(digit[i+1] == 4 && j == 9)){ans += dp[i][j];}}if ((digit[i] == 9 && digit[i + 1] == 4)){break;}}return mem - ans;}int main(){init();int t;long long n;cin >> t;while (t --){cin >> n;cout << solution(n + 1) << endl;}//system("pause");return 0;}整体和2089的思路一样,换了个判断条件而已。
阅读全文
0 0
- HDU 3555 Bomb + HDU 2089 不要62 数位dp入门题目
- HDU 2089 不要62 && HDU 3555 Bomb (数位DP)
- 数位DP入门之hdu 3555 Bomb
- HDU-3555 Bomb (数位dp 入门题)
- hdu 2089 不要62(数位dp入门)
- HDU 2089 不要62 数位dp入门
- hdu 2089 不要62--数位dp入门
- HDU 2089 不要62 数位dp(入门
- HDU 2089 不要62 数位DP入门
- hdu 2089 不要62 数位dp入门
- HDU 2089-不要62(入门数位DP)
- HDU 3555 Bomb (数位DP)
- hdu 3555 - Bomb [数位dp]
- hdu 3555 Bomb【数位DP】
- HDU 3555 Bomb (数位DP)
- hdu 3555 Bomb 数位DP
- HDU 3555 Bomb (数位DP)
- hdu 3555 Bomb 数位dp
- ISR的特点
- JS实现贪吃蛇小游戏
- Visual Studio结合Team Foundation Server和Git进行代码管理
- 利用F5 VE制作F5 11.6.1系统安装引导U盘
- Python自备关键复习点
- HDU 3555 Bomb + HDU 2089 不要62 数位dp入门题目
- C++实现BASE64码编解码
- 内存分配malloc
- 使用cmake编译安装mysql
- CGIC编程
- Excel的VBA学习
- jtable冻结列
- 智能指针之shared_ptr框架源码剖析
- C语言数组长度极限