递推、数位DP解析(以HDU 2089 和 HDU 3555 为例)
HDU 2089 不要62
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=2089
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
0 0
/*
问题
输入一对整数n和m(0<n≤m<1000000), 如果遇到的都是0的整数对表示输入结束
计算并输出有多少不含4和62(必须连号)的数字的个数 解题思路
首先的想法是将1000000以内的符合条件的数打表,然后在区间里数数就行了。
参考网上的解答,这是一道数位DP,那么问题来了什么是数位DP呢?
数位DP就是在根据每个数的各位数字的一些规律,能够得到一些递推关系,从而通过记忆化搜索来解决一些问题的思想。一般是区间内
满足条件的数有多少个,相对于暴力破解,数位DP的解题方法更巧妙,更简洁、高效。 拿不要62这道题来说,不吉利数字要么包含4,要么包含62(必须连号),反过来一个吉利数字需要不能有4,也不能有62
所以定义变量为i和j,表示数字的长度是i,最高位是j
那么状态就是f[i][j],表示数字的长度是i,最高位是j,符合条件的数有多少个
可以根据规律写出如下递推式:
f[i][j]= if (j==4) f[i][j]=0 else if (j!=6) f[i][j]=Σf[i-1][k] (k=0,1,2,3,4,5,6,7,8,9) else if (j==6) f[i][j]=Σf[i-1][k] (k=0,1,3,4,5,6,7,8,9) 有了这个二维表,我们只需要计算一个数x,0到x有多少个符合条件的数,最后左区间减去右区间几位答案。
参考博客:https://blog.csdn.net/zhangxian___/article/details/75304335
*/
#include<cstdio>
#include<cstring>
const int maxn=;
int f[maxn][maxn],c[maxn];
void getf();
long long solve(int n); int main()
{
int n,m;
getf(); while(scanf("%d%d",&n,&m) == && m+n != ){
long long a=solve(m+);
long long b=solve(n); printf("%lld\n",a-b);
}
return ;
} long long solve(int n)
{
int a[]={},i,j,k; i=;
while(n){
a[i++] = n%;
n/=;
}
/*for(j=1;j<i;j++)
printf("@%d ",a[j]);
printf("\n");*/
i--;//长度减一为最高位数字的下标 long long ans=;
for(k=i;k>=;k--){//枚举每一位数字的下标
for(j=;j<a[k];j++){//枚举0到每一位数字减一
if(j != && !(a[k+] == && j == )){
ans += f[k][j];
}
}
if(a[k] == ) break;
if(a[k+] == && a[k] == ) break;
}
return ans;
} void getf()
{
int i,j,k;
memset(f,,sizeof(int)*maxn*maxn);
f[][]=;//0位数最高位是0,初始化为1
for(i=;i<;i++){
for(j=;j<;j++){
if(j == ) f[i][j]=;
else if(j == )
{
for(k=;k<;k++)
f[i][j] += f[i-][k];
f[i][j] -= f[i-][];
}
else
{
for(k=;k<;k++)
f[i][j] += f[i-][k];
}
}
}
/*for(i=1;i<10;i++){
for(j=0;j<10;j++){
printf("%d ",f[i][j]);
}
printf("\n");
}*/
}
题意
给出一个N(1 <= N <= 2^63-1),问1到N中不含49序列的数字有多少个
解题思路
类似这种含某个序列的数的个数,我们可以将其转换成不含某个序列的数,然后用总的个数减去即可。
我们用上面不含62的模板,求出1到N中不含49序列的数的个数,然后用总数减去。不同的是数组可能溢出,需要用long long 存储。
代码:
#include <cstdio>
#include <cstring> typedef long long ll;
const int maxn = ;
ll f[maxn][maxn]; void getf() {
memset(f, , sizeof(ll)*maxn*maxn);
f[][] = ;
for(int i = ; i < maxn; i++) {
for(int j = ; j < ; j++) {
for(int k = ; k < ; k++) {
f[i][j] += f[i - ][k];
}
if(j == )
f[i][j] -= f[i - ][];
}
}
} ll solve(ll x) {
int a[maxn] = {};
int i = ;
while(x) {
a[i++] = x%;
x /= ;
}
ll ans = ;
for(int k = i - ; k >= ; k--) {
for(int j = ; j < a[k]; j++) {
if(!(j == && a[k + ] == ))
ans += f[k][j];
}
if(a[k + ] == && a[k] == ) break;
}
return ans;
} int main()
{
ll n;
int T;
scanf("%d", &T);
while(T--) {
getf();
scanf("%I64d", &n);
printf("%I64d\n", n - solve(n + ) + );
}
return ;
}
递推、数位DP解析(以HDU 2089 和 HDU 3555 为例)的更多相关文章
- [Codeforces676B]Pyramid of Glasses(递推,DP)
题目链接:http://codeforces.com/problemset/problem/676/B 递推,dp(i, j)表示第i层第j个杯子,从第一层开始向下倒,和数塔一样的题.每个杯子1个时间 ...
- 算法技巧讲解》关于对于递推形DP的前缀和优化
这是在2016在长沙集训的第三天,一位学长讲解了“前缀和优化”这一技巧,并且他这一方法用的很6,个人觉得很有学习的必要. 这一技巧能使线性递推形DP的速度有着飞跃性的提升,从O(N2)优化到O(N)也 ...
- 2017"百度之星"程序设计大赛 - 复赛1003&&HDU 6146 Pokémon GO【数学,递推,dp】
Pokémon GO Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- openjudge1768 最大子矩阵[二维前缀和or递推|DP]
总时间限制: 1000ms 内存限制: 65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的 ...
- Uva 10446【递推,dp】
UVa 10446 求(n,bcak)递归次数.自己推出来了一个式子: 其实就是这个式子,但是不知道该怎么写,怕递归写法超时.其实直接递推就好,边界条件易得C(0,back)=1.C(1,back)= ...
- 刷题向》关于一道比较优秀的递推型DP(openjudge9275)(EASY+)
先甩出传送门:http://noi.openjudge.cn/ch0206/9275/ 这道题比较经典, 最好不要看题解!!!!! 当然,如果你执意要看我也没有办法 首先,显然的我们可以用 f [ i ...
- 洛谷4316 绿豆蛙的归宿(DAG递推/概率dp)
题目大意: 给定一个DAG,求起点到终点的路径长度期望 根据题意可以知道每一条边都有一定概率被走到 那么\(\displaystyle\begin{aligned} Ans = \sum_{e \in ...
- hdu 4472 Count(递推即dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4472 代码: #include <cstdio> #include <cstring ...
- 数位DP入门(A - 不要62 HDU - 2089 &&B - Bomb HDU - 3555 )
题目链接:https://cn.vjudge.net/contest/278036#problem/A 具体思路:对于给定的数,我们按照位数进行运算,枚举每一位上可能的数,在枚举的时候需要注意几个条件 ...
随机推荐
- 【Android开发那点破事】打开APP加载页面实现
今天的破事呢就说说APP加载页面的实现.一般情况下,当APP打开的时候,我们需要做很多事情,比如检查网络连接啊,初始化一些配置啊等等.我们可以让这些事情在APP完全打开之前做完,然后呢在打开的过程中显 ...
- hdu 1.2.3
很简单的算法基础题...闰年判断以及计算 #include<iostream> #include<cstdio> using namespace std; int main() ...
- 怎么找到与你Eclipse匹配的spring tool suite插件
在Eclipse中安装插件是很简单的,但是某些插件需要与你的Eclipse的版本对应才能用,比如spring的插件. 首先,查看你的Eclipse的版本. 从eclipse的Help菜单的About ...
- WPF 定义Lookless控件的默认样式、 OnApplyTemplate 如何使用(实现方式、如何工作的)!
写的非常详细: 作者地址:https://www.cnblogs.com/atskyline/archive/2012/11/16/2773806.html 参考资料: http://www.code ...
- Swift5 语言指南(二十) 类型转换
类型转换是一种检查实例类型的方法,或者将该实例视为与其自己的类层次结构中的其他位置不同的超类或子类. Swift中的类型转换是使用is和as运算符实现的.这两个运算符提供了一种简单而富有表现力的方法来 ...
- SSH 学习笔记
零.背景 在看 pm2 的 deploy 功能的时候,对 ssh 的不熟悉导致错误频出,包括之前对 github 的配置也用到了 SSH,所以找个机会整理一下. 一.介绍 SSH 是每一台 Linux ...
- pip指定网址安装
用pip安装库的有时候很慢都动不了 ,访问速度很慢,不稳定等缺陷 所以呢为了解决这个问题只能指定网址源下载的话速度就很快了 pip安装默认访问的是https://pypi.Python.org/sim ...
- iOS-自定义NavigationItem返回按钮【pop返回按钮】
在用navigationVC时,返回按钮有时候不想用系统的,这里用继承的方式把按钮替换了,同时也可以实现系统的右滑返回,很简单: 1.创建基类 BasePopViewController 创建一个用于 ...
- Flask 初印象
Flask 出生于2010年,集中了其他python web框架的长处,定位于微小项目上. 特点 1 内置开发服务器和调试器 2 于Python单元测试功能无缝衔接 Flask框架提供了一个与Pyth ...
- 改变IIS的Framework版本
Changing the Framework version requires a restart of the W3SVC service. Alternatively, you can chang ...