AcWing 1085&HDU2089 不要62【数位DP】

最近在补全提高课所有题目的题解,宣传一下汇总的地方提高课题单+题解(71/220) - AcWing

数位DP基础概念 指路:AcWing 1081. 度的数量【数位DP基本概念+数位DP记忆化搜索】 - AcWing

题目描述

给定正整数区间 [l,r],求该区间内 单独数位上 没有 4 且 相邻数位上 没有 62 的数字个数

分析


想了解 数位DP 基础概念的,可以看一下最上面我贴的链接,这里不会对 重复内容 进行额外讲解

把求 一段区间 的问题,转化为求两个 前缀区间 的问题

本题参数 st 需要记录的参数是:前一位数字是什么

这样就能有效 排除 枚举 62 的情况,而枚举 4 的情况直接 特判 即可

具体请看代码部分(同样我推荐在看过以上思路以后自己先手写一遍,调不出来在看代码,思路不难

Code

 

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 35;

int l, r;
int a[N], al;
int f[N][N];

int dp(int pos, int st, int op)
{
    if (!pos) return 1;
    if (!op && ~f[pos][st]) return f[pos][st];
    int res = 0, maxx = op ? a[pos] : 9;
    for (int i = 0; i <= maxx; i ++ )
        if (i != 4 && (st != 6 || i != 2))
            res += dp(pos - 1, st == -1 && !i ? -1 : i, op && i == a[pos]);
    return op && st == -1 ? res : f[pos][st] = res;
}
int calc(int x)
{
    memset(f, -1, sizeof f); al = 0;
    for ( ; x; x /= 10) a[ ++ al] = x % 10;
    return dp(al, -1, 1);
}
int main()
{
    while (cin >> l >> r, l || r)
    {
        cout << calc(r) - calc(l - 1) << endl;
    }
    return 0;
}

作者:一只野生彩色铅笔
链接:https://www.acwing.com/solution/content/67423/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值