HDU 2089 不要62(数位dp&记忆化搜索)

题目链接[kuangbin带你飞]专题十五 数位DP C - 不要62

题意

杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。

杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。

不吉利的数字为所有含有4或62的号码。例如:

62315 73418 88914

都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。

你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。

思路

dp[i][j]表示当前为第i位且上一位(是/不是)6的数的个数

知道上一位是否为六,对当前为进行if(i!=4 && !(pre&&i==2))即可筛选。记忆化搜索即可。

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <vector>

using namespace std;

int dp[10][2];
int dis[10];

int dfs(int len, bool pre, bool flag)
{
    if(len < 0)
        return 1;
    if(!flag && dp[len][pre]!=-1)
        return dp[len][pre];
    int ans = 0;
    int end = flag?dis[len]:9;
    for(int i=0; i<=end; i++)
    {
        if(i!=4 && !(pre&&i==2))
            ans += dfs(len-1, i==6, flag&&i==end);
    }
    if(!flag)
        dp[len][pre] = ans;
    return ans;
}

int solve(int n)
{
    int len = 0;
    while(n)
    {
        dis[len++] = n%10;
        n /= 10;
    }
    return dfs(len-1, 0, 1);
}

int main()
{
    int l, r;
    memset(dp, -1, sizeof(dp));
    while(~scanf("%d%d", &l, &r) && l && r)
    {
        printf("%d\n", solve(r)-solve(l-1));
    }
    return 0;
}
时间: 2024-10-27 02:06:26

HDU 2089 不要62(数位dp&记忆化搜索)的相关文章

[ACM] hdu 2089 不要62(数位Dp)

不要62 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 19043    Accepted Submission(s): 6442 Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer). 杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就

HDU 2089 不要62(数位DP,三种姿势)

HDU 2089 不要62(数位DP,三种姿势) ACM 题目地址:HDU 2089 题意: 中文题意,不解释. 分析: 100w的数据,暴力打表能过 先初始化dp数组,表示前i位的三种情况,再进行推算 直接dfs,一遍搜一变记录,可能有不饥渴的全部算和饥渴的部分算情况,记录只能记录全部算(推荐看∑大的详细题解Orz) 代码: 1. 暴力 (以前写的) /* * Author: illuz <iilluzen[at]gmail.com> * File: 2089_bf.cpp * Create

[hihocoder 1033]交错和 数位dp/记忆化搜索

#1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0,?a1,?...,?an?-?1,定义交错和函数: f(x)?=?a0?-?a1?+?a2?-?...?+?(?-?1)n?-?1an?-?1 例如: f(3214567)?=?3?-?2?+?1?-?4?+?5?-?6?+?7?=?4 给定 输入 输入数据仅一行包含三个整数,l,?r,?k(0?≤?l?≤?r?≤?1018,?|k|

HDU 2089 不要62 数位DP入门

Problem Description 杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众.不吉利的数字为所有含有4或62的号码.例如:62315 73418 88914都属于不吉利号码.但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列.你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多

HDU 3652 B-number(数位dp&amp;记忆化搜索)

题目链接:[kuangbin带你飞]专题十五 数位DP G - B-number 题意 求1-n的范围里含有13且能被13整除的数字的个数. 思路 首先,了解这样一个式子:a%m == ((b%m)*c+d)%m; 式子的正确是显然的,就不证明了. 那么判断数是否可以被13整除就可以分解为一位一位进行处理. 当然,我们也只需要储存取余后的值. dfs(len, num, mod, flag) mod记录数字对13取余后的值 len表示当前位数 num==0 不含13且上一位不为1 pre==1

hdu 5787 数位dp,记忆化搜索

题意:求区间[l,r]内有多少个数符合,这个数的任意的相邻k位数(digits),这k个数都两两不相等 l,r范围是1~1e18,k是2~5 思路:数位DP,因为K<=5,我们最多需要保存下来当前位的前4位就足够了.因为dp[pos][p1][p2][p3][p4]表示,现在枚举取第pos位,pos位之前的四位分别为p1,p2,p3,p4,p4是pos的上一位.那么p1~p4的范围就是0~9,但是因为总位数小于当前数字的位数的数也要进行枚举,需要一个数字来区分它是前导0还是在中间时为0,令p =

数位dp/记忆化搜索

一.引例 #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数: f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1 例如: f(3214567) = 3 - 2 + 1 - 4 + 5 - 6 + 7 = 4 给定 l, r, k,求在 [l, r] 区间中,所有 f(x) = k 的 x 的和,

bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)

1833: [ZJOI2010]count 数字计数 题目:传送门 题解: 今天是躲不开各种恶心DP了??? %爆靖大佬啊!!! 据说是数位DP裸题...emmm学吧学吧 感觉记忆化搜索特别强: 定义f[i][j][k]表示若前i个位置有k个j的此时的全局方案数,然后就可以记忆化搜索了(具体看代码吧) 代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath>

HDU - 6143 Killer Names(dp记忆化搜索+组合数)

题意:从m种字母中选取字母组成姓名,要求姓和名中不能有相同的字母,姓和名的长度都为n,问能组成几种不同的姓名. 分析: 1.从m种字母中选取i种组成姓,剩下m-i种组成名. 2.i种字母组成长度为n的姓-----可转换成用i种颜色给n个球染色,记忆化搜索 dfs(n,i)---用i种颜色给n个球染色的方案数 先给第1个小球涂色,有m种选择,假设涂色为color[1], 那么剩下n-1个小球: 如果继续使用color[1],则问题转化为用m种颜色给n-1个小球涂色: 如果不再使用color[1],