AcWing
  • 首页
  • 课程
  • 题库
  • 更多
    • 竞赛
    • 题解
    • 分享
    • 问答
    • 应用
    • 校园
  • 关闭
    历史记录
    清除记录
    猜你想搜
    AcWing热点
  • App
  • 登录/注册

AcWing 1083. Windy数【数位DP】    原题链接    中等

作者: 作者的头像   一只野生彩色铅笔 ,  2021-09-16 23:48:45 ,  所有人可见 ,  阅读 2990


25


最近在补全提高课所有题目的题解,宣传一下汇总的地方提高课题解补全计划

数位DP基础概念 指路:【数位DP基本概念+数位DP记忆化搜索】

题目描述

给定正整数区间 $[l, r]$,求该区间内的 $Windy数$ 个数

Windy数 :不含 前导零 且 相邻两个数字 之差 至少 为 $2$ 的 正整数

分析

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

本题进行搜索时 $st$ 需要记录的 参数 是:前一位数位的数字是多少 (唯一需要思考的地方?)

这样就能保证每次枚举数位上的数字,都能符合题目中的需求了

然后就可以直接 套记忆化搜索的板子 了.....

当然也可以额外开 一个参数 记录当前 是否有前导零,带前导零参数的代码:Windy数-作者:凌乱之风

我这样写的话就不用记录前导零 (基本差不多)

#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 (abs(st - i) >= 2)
            res += dp(pos - 1, !i && st == -2 ? -2 : i, op && i == a[pos]);
    return op && st == -2 ? 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, -2, 1);
}
int main()
{
    cin >> l >> r;
    cout << calc(r) - calc(l - 1) << endl;
    return 0;
}

9 评论


用户头像
zwp1314   2021-11-05 15:15      1    踩      回复

大佬,为什么你这个op&&st == -2 可以过,我就必须要op || st == -2 才可以过啊???

用户头像
Bigbos   2022-02-13 21:09      1    踩      回复

我刚才试了一下,op 、op&&st == -2、op || st == -2都是可以过的,第一个时间是最快的,原因应该是把含前导0的状态看成了非法状态,导致重复搜索,个人感觉这里只是在处理记忆化,如果无限制,则后面的数就没有限制,可以随便取0 ~ 9,此时记忆化可以避免重复搜索,如果有限制,就说明之前记忆化的状态可能是有不满足情况的,所以返回计算值,含前导0的状态应该也可以看作是合法的状态,可以记忆化。如有纰漏,望您指出

用户头像
狂气电波   2022-06-26 18:11         踩      回复

我觉得是写错了 如果op==1表示前面都贴上界 但是前面不是全都是前导0 这种情况是第pos位不随意取的dp[pos][last]的值 以后要取dp[pos][last]时取的是lim==0随意取的情况 至于为啥彩铅大佬能过 我也不知道。。。

用户头像
长安炼丹师   2023-03-08 14:15         踩      回复

我也发现了这个问题,op == 1和st == -2只能在第一次进入dfs时成立,后面就无法同时成立了。我把return op && st == -2 ? res : f[pos][st] = res;改为return f[pos][st] = res;也能过。可能数据不够严谨。

用户头像
hua   2024-09-19 10:18         踩      回复

逻辑上来讲应该是或才对


用户头像
今天也是刷题的一天   2023-03-02 17:46         踩      回复

佬,传第二个参数的!i && st == -2 ? -2 : i是什么意思,看半天没懂

用户头像
angsh   2025-05-05 16:15 · 海南         踩      回复

判断这个数位是不是第一位
eg.calc(11)
那么第十位是0时st也应该时-2


用户头像
征途者   2021-09-17 23:28         踩      回复

%%%彩笔dalao

用户头像
一只野生彩色铅笔   2021-09-17 23:33         踩      回复

%%%


App 内打开
你确定删除吗?
1024
x

© 2018-2025 AcWing 版权所有  |  京ICP备2021015969号-2
用户协议  |  隐私政策  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标 qq图标
请输入绑定的邮箱地址
请输入注册信息