[bzoj1026][SCOI2009]windy数_数位dp
windy数 bzoj-1026
题目大意:求一段区间中的windy数个数。
注释:如果一个数任意相邻两位的差的绝对值都不小于2,这个数就是windy数,没有前导0。$区间边界<=2\cdot 10^9$。
想法:数位dp裸题,何为数位dp?
数位dp的意思就是我们交换一种dp的方式。通过数位进行dp。数位dp的主旨分为两点:1.对于所求答案的预处理。2.对于所求区间的边界特判。我们对于数位dp有几个显而易见但是却比较useful的性质:
如果一个数的位数小于第二个数的位数,那么后者是大于前者的。
如果两个数的位数相等且前者的最高位是小于后者的最高位的,那么后者是大于前者的。
如果将两个数同时加减同一个数,他们之间的大小关系显然是不变的。
通过以上几个性质,我们在枚举边界时可以先将位数小的全部枚举,然后对于高位到低位依次dp。
回到这道题,我们先设状态dp[i][j]表示i位数且最高位为j。在转移时,我们其实很容易想到
$\sum\limits_{k=0}^{9}dp(i-1,k)\cdot [|j-k|\ge 2]$
之后,关于边界的处理,看代码... ...
最后,附上丑陋的代码... ...
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef long long ll;
using namespace std;
int f[20][20];
void before_hand()//这个是预处理,在上面说的很清楚了
{
memset(f,0,sizeof f);
for(int i=0;i<=9;i++) f[1][i]=1;
for(int i=2;i<=10;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 dig[20];
ll dispose(ll x)//对边界的处理
{
int ans=0;
int k=0;
memset(dig,0,sizeof dig);
if(!x) return 0;
while(x)
{
dig[++k]=x%10;
x/=10;
}
for(int i=1;i<=k-1;i++) for(int j=1;j<=9;j++)//我们用给出的第一条性质,发现
ans+=f[i][j];//ans这时一定是被所求答案覆盖的
for(int i=1;i<dig[k];i++)//第二个性质
ans+=f[k][i];
for(int i=k-1;i>=1;i--)//反复运用第二、三个性质
{
for(int j=0;j<dig[i];j++)
{
if(abs(j-dig[i+1])>=2) ans+=f[i][j];
}
if(abs(dig[i+1]-dig[i])<2) break;
if(i==1) ans++;
}
return ans;
}
int main()
{
ll l,r;
scanf("%lld%lld",&l,&r);
before_hand();
printf("%lld\n",dispose(r)-dispose(l-1));
return 0;
}
小结:前面预处理的边界不要忘记特判。数位dp的第一道题,加油,JZYshuraK
[bzoj1026][SCOI2009]windy数_数位dp的更多相关文章
- BZOJ_1026_[SCOI2009]windy数_数位DP
BZOJ_1026_[SCOI2009]windy数_数位DP 题意:windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之 ...
- BZOJ1026 SCOI2009 windy数 【数位DP】
BZOJ1026 SCOI2009 windy数 Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B ...
- bzoj1026: [SCOI2009]windy数(数位dp)
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 8203 Solved: 3687[Submit][Sta ...
- 2018.06.30 BZOJ1026: [SCOI2009]windy数(数位dp)
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MB Description windy定义了一种windy数.不含前导零且相邻两 ...
- bzoj 1026 [SCOI2009]windy数(数位DP)
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4550 Solved: 2039[Submit][Sta ...
- 1026: [SCOI2009]windy数(数位dp)
1026: [SCOI2009]windy数 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9016 Solved: 4085[Submit][Sta ...
- BZOJ_1026_[SCOI2009]_windy数_(数位dp)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1026 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为wi ...
- 【BZOJ】1026: [SCOI2009]windy数(数位dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1026 我果然很弱啊... 考虑数位dp.枚举每一位,然后限制下一位即可. 一定要注意啊!在dfs的时 ...
- 1026. [SCOI2009]windy数【数位DP】
Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B,总共有多少个windy数? I ...
随机推荐
- html头部规范书写
建立标准化的声明(DOCTYPE)和head 以前的网页,甚至大型的门户网站也连个声明也没有,就仅仅是<html>,现在要做的就是给你的网页加上声明,规范head区域,让搜索引擎和喜欢你的 ...
- Java之split方法
Java之split方法 1.间隔号"." (1)str.split(".") String str = "10.156.35.87"; S ...
- Excel 2010高级应用-饼图(四)
Excel 2010高级应用-饼图(四) 基本操作如下: 1.新建空白文档,并命名饼图 2.单击"插入",找到饼图样例图 3.选择其中一种饼图图例,单击并在空白文档上生成饼图图框 ...
- Linux显示查看您拥有的仓库
Linux显示查看您拥有的仓库 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ yum repolist all repolist: 0
- Django学习-16-Session
1.保存在服务器的键值对 2.Session做验证时,还要依赖Cookie(重要).当用户登录成功时,生成随机字符串,一份放到Session,一份放到Cookie.当用户再次登录, ...
- 内置函数:filter函数
功能: filter函数用于过滤序列,将满足条件的元素取出来构成新的序列. 用法: filter(function, iterable) 接受两个参数,第一个函数为过滤函数(返回True后者False ...
- JVM GC笔记
堆分区:所有new的对象都会存放在堆中 > 新生代(Young Generation):存放生命周期短的对象,具体还分为Eden和Survivor两个区,其中Survivor分为Fro ...
- 【BZOJ3669】【Noi2014】魔法森林(Link-Cut Tree)
[BZOJ3669][Noi2014]魔法森林(Link-Cut Tree) 题面 题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n ...
- UVa11426 最大公约数之和(正版)
题面 求\(\sum_{i=1}^{n-1}\sum_{j=i+1}^{n}gcd(i, j)\) n<=4000000,数据组数T<=100 答案保证在64位带符号整数范围内(long ...
- 【Webpack的使用指南 01】Webpack入门
使用Webpack有一段时间了,但是感觉之前学的用的都比较零散,所以在这里整理一下Webpack的使用知识,从入门到进阶. 创建项目 首先创建最简单的一个项目 npm init 得到以下项目结构: 安 ...