题目描述:

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

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

输入格式

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

输出格式

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

数据范围

1≤A≤B≤2×10^9

输入样例1:

1 10

输出样例1:

9

输入样例2:

25 50

输出样例2:

20

分析:

方法一:动态规划

本题是简单的数位DP问题,唯一要注意的是对前导0的处理。状态表示f[i][j]表示i为数最高位是j的windy数的个数,不过与上一题的表示不同的是,本题的i位数不包括前导零,也就是像014这样的数不会记入长度为i的windy数内,但是024会记入。这么说可能不明白,尽管去掉0后14是windy数,但是一旦再加上一位比如2014,显然就不是windy数了,而2024依旧是windy数,所以前导0在符合windy数性质情况下才会被记入f[i][j]。设n = abcde,在枚举最高位时,我们先不去枚举最高位是0的情况,在枚举完其他情况后再加上所有位数小于n的位数的windy数即可(因为这时的f数组会少统计0开头的windy数),而对于非最高位比如b所在的位置,当b不是0时,我们完全可以加上f[i + 1][0],因为只有前导0也合法的windy数才能被接入b所在位置的后面。举个例子就是n = 400时,枚举第一位是0的时候,f[3][0]只统计了024之类的合法windy数,并未统计014这样去掉前导0后合法的windy数,所以暂时不去统计首位是0的情况。而枚举第二位是0的情况时,比如203是合法的,201不合法,f[2][0]并未统计01这样不合法的windy数,所以可以加上。具体的实现细节都是同一套模板,不再赘述,见代码:

#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
const int N = 12;
int f[N][N];
void init(){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 get(int n){if(!n)  return 0;vector<int> num;while(n)    num.push_back(n % 10),n /= 10;int res = 0,last = -2;for(int i = num.size() - 1;i >= 0;i--){int x = num[i];if(x){for(int j = 1;j < x;j++){if(abs(j - last) >= 2)  res += f[i + 1][j];}if(last >= 2)  res += f[i+1][0];//不是最高位时,加上0开头的windy数}if(abs(x - last) < 2)   break;last = x;if(!i)  res++;}for(int i = 1;i < num.size();i++){//加上最高位是0的windy数for(int j = 1;j <= 9;j++){res += f[i][j];}}return res;
}
int main(){int A,B;cin>>A>>B;init();cout<<get(B) - get(A - 1)<<endl;return 0;
}

方法二:记忆化搜索

写完这题的记忆化搜索后,发现不仅DP的写法是一个套路,数位DP的dfs的写法也如出一辙,在上一题的基础上稍加改动即可。dfs的参数有当前枚举的位置u,上一个位置上的数pre,前面位置上枚举的数字是否已经小于了n的标志位flag。本题还要加一个参数zero表示之前枚举的位置是否都是0,如果都是0,那么枚举第u位就可以不受windy数规则的限制了,如果不是0,则还需要受规则的限制。

#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 12;
int len,num[N],f[N][N][2][2];
int dfs(int u,int pre,int flag,int zero){if(f[u][pre][flag][zero] != -1) return f[u][pre][flag][zero];if(!u)  return 1;int t,res = 0;for(int i = 0;i <= 9;i++){if(!zero && abs(i - pre) < 2)    continue;t = 0;if(zero && !i)  t = 1;if(flag && i >= num[u]){if(i == num[u]) res += dfs(u - 1,i,1,t);break;}else    res += dfs(u - 1,i,0,t);}return f[u][pre][flag][zero] = res;
}
int get(int n){if(n < 10)  return n + 1;len = 0;while(n)    num[++len] = n % 10,n /= 10;memset(f,-1,sizeof f);return dfs(len,0,1,1);
}
int main(){int a,b;while(cin>>a>>b){cout<<get(b) - get(a - 1)<<endl;}return 0;
}

AcWing 1083 Windy数相关推荐

  1. Acwing 1083. Windy数

    Acwing 1083. Windy数 题意: Windy 定义了一种 Windy 数:不含前导零且相邻两个数字之差至少为 2 的正整数被称为 Windy 数. Windy 想知道,在 A 和 B 之 ...

  2. 1083 Windy数(数位dp)

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

  3. 1083. Windy数

    题目 题意: 求给定区间内的不含前导零且相邻两个数字之差至少为 2 的正整数. 思路: 数位dp.这里注意一点是有前导零的情况,即只有个位数前边是0的情况,这个是可以无脑放的. 时间复杂度: O(能过 ...

  4. windy数(数位dp)

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

  5. bzoj-1026 windy数

    题意: 定义一种windy数.这个数在十进制下相邻两个数字之差至少为2的正整数: 求区间[A,B]的这样的数的个数: n<=10^9: 题解: 数位乱搞. 首先求区间[A.B]等价于求[1,A- ...

  6. bzoj 1026 windy数

    题目大意: 定义一种windy数:不含前导零且相邻两个数字之差至少为2的正整数被称为windy数 求在A和B之间,包括A和B,总共有多少个windy数 思路: 一眼数位dp 具体见注释 1 #incl ...

  7. luoguP2657 [SCOI2009]windy数

    和诸位巨佬不同,蒟蒻如我,只能想到怎么统计不满足windy数条件的数 就是个爆搜 定义c[i][j][k]表示第i位且前一位为j,k表示是否满足条件 1 #include<bits/stdc++ ...

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

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

  9. uestc 250 windy数(数位dp)

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

最新文章

  1. 基于Android移动终端的微型餐饮管理系统的设计与实现1-简介
  2. Java 15 转正了,国内几大互联网公司均有贡献,其中腾讯最为突出!
  3. VC mfc 多文档程序更改子文档标题名
  4. 使用springcloud gateway搭建网关(分流,限流,熔断)
  5. 囚犯生存概率引发的循环思考
  6. 数据时代,信息的无处遁形
  7. [收藏]Web创业的10条戒律
  8. Hdu 1303 Doubles
  9. 团队的远程管理_管理远程团队的4种方法
  10. python解四元一次方程_sympy 解四元一次方程
  11. MACHINE LEARNING ----BY HUNGYILEE (love u)
  12. matplotlib.pyplot 标记出曲线上最大点和最小点的位置
  13. 第二章 试验资料的整理与特征数的计算
  14. 微信小程序手机号-springboot
  15. 计算机为啥系统保护设置不了,我的电脑为什么设置了屏幕保护程序而不起作用 – 手机爱问...
  16. JavaScript判断输入的数是不是素数
  17. JS文件应该放在什么位置
  18. oracle aul 恢复,使用AUL-MyDUL恢复的步骤
  19. 双碑零基础西班牙语学习 从0开始的西班牙语常识
  20. python api开发框架_python api框架

热门文章

  1. 阅读---读吴军博士《态度》有感
  2. 转《MCU低功耗设计》
  3. BOM 物料清单 Bill Of Materials
  4. 3分钟掌握7个XD基础操作
  5. PS制作五彩抽象人像
  6. java后端研发经典面试题总结二
  7. 业绩承压来临,京东方还能抗周期多久
  8. python实战笔记之(8):下载知乎视频
  9. 【解决方案】Error response from daemon: Conflict. The container name /mongo is already in use by contain
  10. xpath用于HTML文档通过元素,理解HTML和XPath