HDU 2089 不要62

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=2089

Problem Description
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
 
Input
输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。
 
Output
对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
 
Sample Input
1 100
0 0
 
Sample Output
80
 
 /*
问题
输入一对整数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");
}*/
}

HDU 3555 Bomb

题意

给出一个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 为例)的更多相关文章

  1. [Codeforces676B]Pyramid of Glasses(递推,DP)

    题目链接:http://codeforces.com/problemset/problem/676/B 递推,dp(i, j)表示第i层第j个杯子,从第一层开始向下倒,和数塔一样的题.每个杯子1个时间 ...

  2. 算法技巧讲解》关于对于递推形DP的前缀和优化

    这是在2016在长沙集训的第三天,一位学长讲解了“前缀和优化”这一技巧,并且他这一方法用的很6,个人觉得很有学习的必要. 这一技巧能使线性递推形DP的速度有着飞跃性的提升,从O(N2)优化到O(N)也 ...

  3. 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 ...

  4. openjudge1768 最大子矩阵[二维前缀和or递推|DP]

    总时间限制:  1000ms 内存限制:  65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的 ...

  5. Uva 10446【递推,dp】

    UVa 10446 求(n,bcak)递归次数.自己推出来了一个式子: 其实就是这个式子,但是不知道该怎么写,怕递归写法超时.其实直接递推就好,边界条件易得C(0,back)=1.C(1,back)= ...

  6. 刷题向》关于一道比较优秀的递推型DP(openjudge9275)(EASY+)

    先甩出传送门:http://noi.openjudge.cn/ch0206/9275/ 这道题比较经典, 最好不要看题解!!!!! 当然,如果你执意要看我也没有办法 首先,显然的我们可以用 f [ i ...

  7. 洛谷4316 绿豆蛙的归宿(DAG递推/概率dp)

    题目大意: 给定一个DAG,求起点到终点的路径长度期望 根据题意可以知道每一条边都有一定概率被走到 那么\(\displaystyle\begin{aligned} Ans = \sum_{e \in ...

  8. hdu 4472 Count(递推即dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4472 代码: #include <cstdio> #include <cstring ...

  9. 数位DP入门(A - 不要62 HDU - 2089 &&B - Bomb HDU - 3555 )

    题目链接:https://cn.vjudge.net/contest/278036#problem/A 具体思路:对于给定的数,我们按照位数进行运算,枚举每一位上可能的数,在枚举的时候需要注意几个条件 ...

随机推荐

  1. 团队项目(HCL)

    一.团队展示 队名:盐酸队 队员学号及风采: 团队项目描述:经典90坦克大战(基于java) 团队合照: 二.团队选题 经典90坦克大战是以坦克为题材的射击类小游戏,我们将在java上实现并拓展,我们 ...

  2. 使用 ipmitool 实现远程管理Dell 系列服务器

    IBM 文档:       http://www.ibm.com/developerworks/cn/linux/l-ipmi/index.html ipmi命令收集: http://hi.baidu ...

  3. unigui web app之菜单

    unigui web app之菜单 拖放TUnimMenu控件到窗体上. side:=msleft 表示将在左边显示菜单. 菜单项属性 UnimMenu1.Visible := True;显示菜单 U ...

  4. Delphi 在DLL中使用DevExpress控件时出错解决办法

    测试环境 DevExpress VCL 14.1.3 和XE7 问题:在dll使用cxGrid控件时  如果不添加列标题 则不报错   查询无数据集显示,如果加上标题 就报错了 这段为报错部分 fun ...

  5. 控制uniFrame显示的一个管理类

    控制uniFrame显示的一个管理类 (2016-03-29 06:41:17) 转载▼ 标签: delphi 分类: uniGUI 利用uniGUI Frame的机制来搭建项目,是非常好的实现方式, ...

  6. python threading模块

    #coding=utf-8 import threading from time import ctime,sleep def music(func): for i in range(2): prin ...

  7. 识别同音字词pypinyin, 分词 jieba

    一.pypinyin 在处理语音输入指令时, 比如 请给圆圆发消息,那么转化为文字识别时, 无法确定转换的是圆圆还是园园或是源源, 为了解决这个问题, 就把指令转换为拼音来处理,这样就可以处理同音字了 ...

  8. 微服务统一登陆认证怎么做?JWT ?

    无状态登录原理 1.1.什么是有状态? 有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session. 例如登录:用户登 ...

  9. Java Calender 类详解

    一.   如何创建 Calendar 对象 Calendar 是一个抽象类, 无法通过直接实例化得到对象. 因此, Calendar 提供了一个方法 getInstance,来获得一个Calendar ...

  10. 小猴打架(luogu4430)(数论+生成树计数)

    一开始森林里面有\(N\)只互不相识的小猴子,它们经常打架,但打架的双方都必须不是好朋友.每次打完架后,打架的双方以及它们的好朋友就会互相认识,成为好朋友.经过\(N-1\)次打架之后,整个森林的小猴 ...