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. 数据统计--union all 执行多条sql

    需求--统计hive某张表type字段不同取值的数据量 我们已知某张表的type的取值是1,2,3,4,5,想要统计不同type的数据量,并清晰的展现出来.可以通过union all 的方式,sql如 ...

  2. unidbgrid列排序

    unidbgrid列排序 1)指定列的.sortable:=true; 2)unidbgrid.columnsort事件添加如下代码: if SameText(Column.FieldName, 'I ...

  3. Android-Java-同步方法-synchronized

    1.方法具有封装性: /** * 1.方法具有封装性: */ public void addMoney(double moneyAsset) { this.moneyAsset += moneyAss ...

  4. win10 开机背景图

    地址 C:\Users\*\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalSta ...

  5. C/C++掌握技能(三)

    #include<cstdio> ][]={ //平年和闰年的每个月的天数 {,},{,},{,},{,},{,},{,},{,}, {,},{,},{,},{,},{,},{,} }; ...

  6. LOJ#3093. 「BJOI2019」光线(递推+概率期望)

    题面 传送门 题解 把\(a_i\)和\(b_i\)都变成小数的形式,记\(f_i\)表示\(1\)单位的光打到第\(i\)个玻璃上,能从第\(n\)个玻璃下面出来的光有多少,记\(g_i\)表示能从 ...

  7. Python大黑阔—url采集+exp验证,带你批量测试

    i春秋作家:大木瓜 前言: 最近几天在整理从各处收集来的各种工具包,大大小小的塞满了十几个G的硬盘,无意间发现了一个好几年前的0day.心血来潮就拿去试了一下,没想到真的还可以用,不过那些站点都已经老 ...

  8. mongoose入门

    概述 像Mysql和Mongodb这样的数据库,一般都是在命令行或者工具里面进行操作,如果想在node搭建的服务器上面操作,就必须要利用特殊的模块的.其中操作Mongodb数据库需要用到mongoos ...

  9. [JavaScript] 根据指定宽度截取字符串

    /** * 根据指定宽度截取字符串 * @param desc 原始字符串 * @param width 该显示的宽度 * @param fontsize 字体大小 12px * @returns { ...

  10. 【hyperscan】hyperscan开源了!

    hyperscan开源了! 官网:https://01.org/zh/hyperscan 1. 新闻背景 当地时间10月19日,intel将它的高速正则表达式匹配引擎hyperscan开源了,版本4. ...