【bzoj1026】[SCOI2009]windy数 数位dp
题目描述
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的更多相关文章
- BZOJ1026: [SCOI2009]windy数[数位DP]
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 6346 Solved: 2831[Submit][Sta ...
- [bzoj1026][SCOI2009]windy数——数位dp
题目 求[a,b]中的windy数个数. windy数指的是任意相邻两个数位上的数至少相差2的数,比如135是,134不是. 题解 感觉这个题比刚才做的那个简单多了...这个才真的应该是数位dp入门题 ...
- HDU2089 不要62 BZOJ1026: [SCOI2009]windy数 [数位DP]
基础题复习 这次用了dfs写法,感觉比较好 #include <iostream> #include <cstdio> #include <cstring> #in ...
- 【BZOJ-1026】windy数 数位DP
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5230 Solved: 2353[Submit][Sta ...
- bzoj 1026 [SCOI2009]windy数 数位dp
1026: [SCOI2009]windy数 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline ...
- luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索
题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...
- 题解 BZOJ1026 & luogu P2657 [SCOI2009]windy数 数位DP
BZOJ & luogu 看到某大佬AC,本蒟蒻也决定学习一下玄学的数位$dp$ (以上是今年3月写的话(叫我鸽神$qwq$)) 思路:数位$DP$ 提交:2次 题解:(见代码) #inclu ...
- 洛谷P2657 [SCOI2009]windy数 [数位DP,记忆化搜索]
题目传送门 windy数 题目描述 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B,总共有多少个win ...
- P2657 [SCOI2009]windy数 数位dp
数位dp之前完全没接触过,所以NOIP之前搞一下.数位dp就是一种dp,emm……用来求解区间[L,R]内满足某个性质的数的个数,且这个性质与数的大小无关. 在这道题中,dp[i][j]代表考虑了i位 ...
随机推荐
- 北京Uber优步司机奖励政策(4月3日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 北京Uber优步司机奖励政策(3月17日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- OpenCV 3.2 Viz 3D可视化
该可视化模块提供了坐标系变化,3D动画等功能 最简单的显示坐标系 viz::Viz3d window("window"); window.showWidget("Coor ...
- nio之netty3的应用
1.netty3是nio的封装版本.在使用上面比nio的直接使用更好.nio简单使用都是单线程的方式(比如:一个服务员服务很多客户),但是netty3的方式不一样的是,引入线程池的方式来实现服务的通信 ...
- php 用continue加数字实现foreach 嵌套循环中止
foreach($array as $key => $value) { if($value == 5)break; } // 这是一种. // 如果是嵌套的循环,用continue加数字也可以实 ...
- P/Invoke 光标的操作
获取与设置光标在屏幕上的位置 GetCursorPos 获取光标在屏幕上的位置,光标位置始终是在屏幕坐标纵指定的,并且不受包含光标的窗口映射模式的影响 函数原型: BOOL GetCursorPos( ...
- Selenium 入门到精通系列:三
Selenium 入门到精通系列 PS:Driver_Element 常用方法 例子 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2 ...
- Python序列及其操作(常见)
python序列及函数入门认识: 0. 我们根据列表.元组和字符串的共同特点,把它们三统称为什么? 序列,因为他们有以下共同点: 1)都可以通过索引得到每一个元素 2)默认索引值总是从0开始(当 ...
- Unity初探—SpaceShoot
Unity初探—SpaceShoot DestroyByBoundary脚本(C#) 在游戏中我们添加了一个Cube正方体,让他来作为游戏的边界.它是可以触发触发事件的(勾选Is Trigger),当 ...
- hexo部署失败如何解决