题目描述

Windy 定义了一种 Windy 数:不含前导零且相邻两个数字之差至少为 2 的正整数被称为 Windy 数。

Windy 想知道,在 A 和 B 之间,包括 A 和 B,总共有多少个 Windy 数?

输入格式

共一行,包含两个整数 A 和 B。

输出格式

输出一个整数,表示答案。

数据范围

1≤A≤B≤2×1091≤A≤B≤2×10^91≤A≤B≤2×109

输入样例1

1 10

输出样例1

9

输入样例2

25 50

输出样例2

20

算法思想

根据题目描述求一个区间 [A,B][A,B][A,B]中、有多少个满足不含前导零相邻两个数字之差至少为 2的数字个数 。用数位DP的思想进行分析,例如求区间 [A,B][A,B][A,B]中符合条件的数的个数:

  1. 实现函数dp(n)求区间 [1,n][1,n][1,n]中符合条件的数的个数
  2. dp(B) - dp(A - 1)求区间 [A,B][A,B][A,B]中符合条件的数的个数

dp(n)可以用分类谈论的方法进行计算。在不能超过n的情况下,从最高位开始向下枚举数n的每一位a[i],计算出区间[1−n][1-n][1−n]所有符合条件的方案。

如果从集合划分的角度进行分析,可以将所有分类用一棵二叉树表示出来。如下图所示:

  1. 左侧分支表示所有符合条件的数中第i位小于a[i]的情况,即0−a[i]−10-a[i] - 10−a[i]−1。此时,剩余i位的数字任意取都不会超过n,因此这一类的方案可以通过预先处理出i位数字且最高位不超过a[i] - 1的方案数(相邻两个数字之差至少为 2),然后进行累加即可。
  2. 右侧分支表示所有符合条件的数中第i位等于a[i]的情况,此时继续向下分类讨论即可。
  3. 最后一位a[0]单独处理,如果能走到最右侧结点a[0],说明数字n也是满足条件的,此时总方案数增加1

注意:对含前导零的数字需要特殊处理,例如137是符合要求的,但是0137就不符合要求了,因此对于位数比n少的数字需要特殊处理。

算法实现

  1. 预处理出f[i][j],表示有i位数字且最高位为j的数字集合中,相邻两个数字之差至少为 2的方案数。状态计算:f[i][j]=∑f[i−1][k]f[i][j] = \sum{ f[i - 1][k] }f[i][j]=∑f[i−1][k],其中 ∣j−k∣≥2\vert j-k\vert\ge2∣j−k∣≥2
  2. 预处理出数字n的每一位a[i]
  3. 从高位到低位枚举,累加每一位上符合条件的方案数。
  4. 累加位数比n少的数字且满足要求的方案。

代码实现

#include <iostream>
#include <vector>
using namespace std;
const int N = 11;
//f[i][j]表示i位数且最高位为j时的Windy数的个数
int f[N][N];
void init()
{//初始化位数为1时的状态for(int i = 0; i <= 9; i ++) f[1][i] = 1;//状态计算for(int i = 2; i < N; i ++)for(int j = 0; j <= 9; j ++){for(int k = 0; k <= 9; k ++)if(abs(j - k) >= 2) f[i][j] += f[i - 1][k];}
}int dp(int n)
{//n为0时,方案数为0if(!n) return 0;vector<int> a;while(n) a.push_back(n % 10), n /= 10;//注意这里last表示上一位数字,初始化为-2,保证最高位为1时也满足条件int res = 0, last = -2;for(int i = a.size() - 1; i >= 0; i --){int x = a[i];//累加左侧分支的情况//如果i是最高位,则j从1开始枚举//否则j从0开始枚举for(int  j = i == a.size() - 1; j < x; j ++){if(abs(j - last) >= 2)res += f[i + 1][j];}//没有右侧分支if(abs(x - last) < 2) break;last = x;if(!i) res ++;}// 特殊处理有前导零的数,即位数小于n的windy数for (int i = 1; i < a.size(); i ++ )for (int j = 1; j <= 9; j ++ )res += f[i][j];return res;
}int main()
{init();int a, b;cin >> a >> b;cout << dp(b) - dp(a - 1) << endl;return 0;
}

数位动态规划:Windy数相关推荐

  1. 数位DP --Windy数

    满足一下条件的数字称为windy数 不考虑前导0,所有相邻的两个数字的差至少为2. 求出任意区间内的所有windy数 思路:dp[i][j]表示所有长度为 i 的数字以 j 开头的windy数的个数. ...

  2. windy数(数位dp)

    1. 问题描述: windy 定义了一种 windy 数.不含前导零且相邻两个数字之差至少为 2 的正整数被称为 windy 数. windy 想知道,在 A 和 B 之间,包括 A 和 B,总共有多 ...

  3. bzoj 1026: [SCOI2009]windy数 数位DP算法笔记

    数位DP入门题之一 也是我所做的第一道数位DP题目 (其实很久以前就遇到过 感觉实现太难没写) 数位DP题目貌似多半是问从L到R内有多少个数满足某些限制条件 只要出题人不刻意去卡多一个$log$什么的 ...

  4. uestc 250 windy数(数位dp)

    题意:不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? 思路:数位dp #include<iostream ...

  5. 【bzoj1026】[SCOI2009]windy数 数位dp

    题目描述 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? 输入 包含两个整数 ...

  6. BZOJ1026 [SCOI2009]windy数 数位dp

    欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1026 题目概括 求区间[A,B]中有多少数满足下面的条件. 条件:该数相邻两位之差不小于2. 题解 ...

  7. 【BZOJ1026】windy数,数位DP

    Time:2016.08.14 Author:xiaoyimi 转载注明出处谢谢 思路: 依旧蛋疼的数位DP f[i][j]表示有i位,且最高位为j的windy数个数 转移方程比较好写 关键是具体求值 ...

  8. 洛谷2657 windy数(数位DP)

    传送门 [题目分析] 数位DP经典题了. 考虑直接统计R内的windy数和L-1内的windy数,两者相减即为L~R之间的windy数. 考虑DP,记录当前位以及上一位所填的数,当前是否前面为前导零, ...

  9. AcWing1083. Windy数(数位DP)题解

    题目传送门 题目描述 Windy 定义了一种 Windy 数:不含前导零且相邻两个数字之差至少为 2 的正整数被称为 Windy 数. Windy 想知道,在 A 和 B 之间,包括 A 和 B,总共 ...

最新文章

  1. 头条面试官:NIO 是不是就是I/O多路复用?我:不是
  2. Java、Android注解代码生成(ButterKnife原理、ViewBinding)
  3. 0046算法笔记——【随机化算法】舍伍德随机化思想解决跳跃表问题
  4. 【Linux】33. shell脚本 递归删除空目录
  5. 在pycharm创建scrapy项目
  6. Sqoop2开启Kerberos安全模式
  7. 关于scanf 函数,你很少了解的“秘密”
  8. Volley的原理解析
  9. SOLARIS UFS文件系统解析
  10. root用户改动普通用户文件
  11. php隐藏json数据,PHP调用出json后出来的数目字 想隐藏掉 50份求高手帮忙下
  12. JDK安装包和Mysql安装包整理
  13. spyder python下载_spyder中文版下载-spyder pythonv4.1.3 官方最新版下载__飞翔下载
  14. 编写谷歌浏览器插件入门
  15. 腾讯的星星海服务器芯片,腾讯云星星海重磅发布两款自研新品 打造软硬一体云计算基础设施...
  16. ionic介绍以及ionic环境搭建
  17. 平面设计完全手册_什么是平面设计,做平面设计都要了解哪些基础知识点?
  18. mysql独立开发_TickyCMS: TickyCMS是由罗敏贵独自开发的一款基于PHP+Mysql架构的轻量级开源内容管理系统。...
  19. 基于cocos2d-x引擎的游戏框架设计【转载】
  20. java电影院购票系统概况_电影院售票管理系统

热门文章

  1. 摩托车高级驾驶员辅助系统(ADAS)的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  2. Matlab入门(隐藏图片)
  3. Debian 安装手记
  4. vim实用指南(9)vimdiff好用的可视化文本对比工具
  5. 空白脂质体冻干粉制备以及荧光素修饰空白脂质体的应用
  6. 使用 Nginx 部署前后端分离项目,解决跨域问题
  7. [算法入门笔记] 18. 动态规划
  8. 【笔记】《Python数据分析与实战挖掘》
  9. 蓝桥杯 2018 C++ A组 初赛部分题解
  10. 自动化脚本腾讯云配置集群(三)批量修改host