题目描述

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

输入

包含两个整数,A B。

输出

一个整数,表示答案

样例输入

【输入样例一】
1 10
【输入样例二】
25 50

样例输出

【输出样例一】
9
【输出样例二】
20


题解

数位dp

快联赛了重写了一下,发现以前写的太傻逼了= =

由于加一个数位的贡献只与最高位有关,因此设 $f[i][j]$ 表示 $i$ 位数,最高位为 $j$ 的数的个数。

那么显然可以得到 $f[i][j]=\sum\limits_{|j-k|\le 2}f[i-1][k]$ 。

预处理出 $f$ 数组后即可进行数位dp。

先把位数不满的算上,然后再从高位到低位把该位不满的加入答案中。

此时需要记录上一个数位是什么,在枚举当前数位时需要满足当前位的条件。并且如果上一个与当前数位产生冲突则不再有满足条件的数,应当跳出循环。

把询问区间转化为 $[1,n)$ 的半开半闭区间更容易处理一些。

代码中为了避免一些细节(比如最高位只能处理到 $2*10^9$ 之类的),开了long long。

#include <cstdio>
typedef long long ll;
ll f[11][10] , b[11];
inline int abs(int x)
{
return x > 0 ? x : -x;
}
void init()
{
int i , j , k;
b[0] = 1 , b[1] = 10;
for(i = 0 ; i < 10 ; i ++ ) f[1][i] = 1;
for(i = 2 ; i < 11 ; i ++ )
{
b[i] = b[i - 1] * 10;
for(j = 0 ; j < 10 ; j ++ )
for(k = 0 ; k < 10 ; k ++ )
if(abs(j - k) >= 2)
f[i][j] += f[i - 1][k];
}
}
ll calc(ll n)
{
int i , j , last = -1 , di = 1;
ll ans = 0;
for(i = 1 ; b[i] <= n ; i ++ )
for(j = 1 ; j < 10 ; j ++ )
ans += f[i][j];
for( ; i ; i -- )
{
for(j = di ; j < n / b[i - 1] % 10 ; j ++ )
if(abs(j - last) >= 2)
ans += f[i][j];
if(abs(n / b[i - 1] % 10 - last) < 2) break;
last = n / b[i - 1] % 10 , di = 0;
}
return ans;
}
int main()
{
init();
ll n , m;
scanf("%lld%lld" , &n , &m);
printf("%lld\n" , calc(m + 1) - calc(n));
return 0;
}

【bzoj1026】[SCOI2009]windy数 数位dp的更多相关文章

  1. BZOJ1026: [SCOI2009]windy数[数位DP]

    1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 6346  Solved: 2831[Submit][Sta ...

  2. [bzoj1026][SCOI2009]windy数——数位dp

    题目 求[a,b]中的windy数个数. windy数指的是任意相邻两个数位上的数至少相差2的数,比如135是,134不是. 题解 感觉这个题比刚才做的那个简单多了...这个才真的应该是数位dp入门题 ...

  3. HDU2089 不要62 BZOJ1026: [SCOI2009]windy数 [数位DP]

    基础题复习 这次用了dfs写法,感觉比较好 #include <iostream> #include <cstdio> #include <cstring> #in ...

  4. 【BZOJ-1026】windy数 数位DP

    1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 5230  Solved: 2353[Submit][Sta ...

  5. bzoj 1026 [SCOI2009]windy数 数位dp

    1026: [SCOI2009]windy数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline ...

  6. luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索

    题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...

  7. 题解 BZOJ1026 & luogu P2657 [SCOI2009]windy数 数位DP

    BZOJ & luogu 看到某大佬AC,本蒟蒻也决定学习一下玄学的数位$dp$ (以上是今年3月写的话(叫我鸽神$qwq$)) 思路:数位$DP$ 提交:2次 题解:(见代码) #inclu ...

  8. 洛谷P2657 [SCOI2009]windy数 [数位DP,记忆化搜索]

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

  9. P2657 [SCOI2009]windy数 数位dp

    数位dp之前完全没接触过,所以NOIP之前搞一下.数位dp就是一种dp,emm……用来求解区间[L,R]内满足某个性质的数的个数,且这个性质与数的大小无关. 在这道题中,dp[i][j]代表考虑了i位 ...

随机推荐

  1. Chrome模拟平板调试

    1. 按F12,打开开发者工具,右上角,点击红圈中的标志.然后在弹出的面板中点击'Emulation'. 2. 会看到左侧的四个选项卡  Device 设备.Screen 屏幕.User Agent ...

  2. beego orm mysql

    beego框架中的rom支持mysql 项目中使用到mvc模式,总结下使用方式: models中 package models import ( //使用beego orm 必备 "gith ...

  3. mysql数据库基本操作命令

    1.登录命令 mysql -u root -p "password" 2.列出所有数据库 show databases; 3.使用数据库 use db_name 4.列出数据库中所 ...

  4. TPO-13 C2 How to use language lab

    TPO-13 C2 How to use language lab 第 1 段 1.Listen to a conversation between a student and the languag ...

  5. 统计hive库表在具体下所有分区大小

    1 查询具体表分区大小,以字节展示 hadoop fs -du /user/hive/warehouse/treasury.db/dm_user_excercise > dm_user_exce ...

  6. 复合词 (Compund Word,UVa 10391)

    题目描述: 题目思路: 用map保存所有单词赋键值1,拆分单词,用map检查是否都为1,即为复合词 #include <iostream> #include <string> ...

  7. 孤荷凌寒自学python第八十五天配置selenium并进行模拟浏览器操作1

    孤荷凌寒自学python第八十五天配置selenium并进行模拟浏览器操作1 (完整学习过程屏幕记录视频地址在文末) 要模拟进行浏览器操作,只用requests是不行的,因此今天了解到有专门的解决方案 ...

  8. 【转】《王者荣耀》技术总监复盘回炉历程:没跨过这三座大山,就是另一款MOBA霸占市场了

    如今已经大获市场成功的<王者荣耀>一直是业内各方关注的对象,而我们也知道这款产品在成为国民级游戏之前,也遇到过一段鲜有人知的调优期.也就是在2015年8月18号正式不删档测试版本推出之后, ...

  9. python 打包

    一.下载 pip install Pyinstaller 二.使用Pyinstaller 1.使用下载安装的方式安装的Pyinstaller打包方式 将需要打包的文件放在解压得到的Pyinstalle ...

  10. Dask教程

    Dask 介绍 Dask是一款用于分析计算的灵活并行计算库. Dask由两部分组成: 针对计算优化的动态任务调度.这与Airflow,Luigi,Celery或Make类似,但针对交互式计算工作负载进 ...