题目链接

https://www.luogu.org/problemnew/show/P2657

分析

第一道数位DP题,发现有点意思

DP求\([L,R]\)区间内的XXX个数,很套路地想到前缀和,先求\([1,R],[1,L]\)相减就好了

状态转移也明确,发现状态只和上一位数位的数有关,\(f[i][j]\)表示第\(i\)位放\(j\)的话有多少个windy数,注意的这里的windy数是在钦定一个数字最高位是多少情况下所有的windy数的数量和(即[1,i-1]位放数情况都被算了一遍)

\(f[i][j] = f[i-1][ j-2/j+2]\)

然后考虑怎么求答案.

假如我们要求\(1\)到\(R\)中的windy数有多少,设R有x位,第i位数字为num[i]

首先对于位数小于\(x\)的以及第\(x\)位数字小于\(num[x]\)都可以算进去

然后考虑卡到R边界的情况,我们可以枚举前k位卡到了上限即前\(k\)位与R的前\(k\)位相同,那么在第\(k+1\)位进行答案统计

首先我们是不能达到上界的(这样的话可能算多次),在枚举\(k+1\)位的数字为\(d\)时根据定义只有当\(abs(d-a[k])>=2\)时才能累计答案

但是还有一个问题就是你本身枚举与R相等的前k位数可能就违反了windy数的定义,那么我们需要特判一下退出,但是还需要注意由于这个原因我们需要倒序枚举,因为正序枚举的话如果你前面有一对数是非法的,无论后面数位为何值整个数就是非法的

还有一些奇奇怪怪的问题比如前导\(0\).不过这个也挺好想的.

最后发现如果\(R\)也是个windy数的话没判到(我们的卡上界实际上是没有卡到的,我们总是在当前枚举的这一位比R小),所以特判一下就好了

代码

/*code by RyeCatcher
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <utility>
#include <queue>
#include <vector>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <iostream>
#define DEBUG freopen("dat.in","r",stdin);freopen("wa.out","w",stdout);
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define ri register int
#define ll long long
#define ull unsigned long long
#define SIZE 1<<22
using std::min;
using std::max;
using std::priority_queue;
using std::queue;
using std::vector;
using std::pair;
using namespace __gnu_pbds;
inline char gc(){static char buf[SIZE],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,SIZE,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
template <class T>inline void read(T &x){x=0;int ne=0;char c;while((c=gc())>'9'||c<'0')ne=c=='-';x=c-48;while((c=gc())>='0'&&c<='9')x=(x<<3)+(x<<1)+c-48;x=ne?-x:x;return ;
}
const int maxn=12;
const int inf=0x7fffffff;
int a,b;
int toa=0,numa[maxn],tob=0,numb[maxn],f[maxn][maxn];
int main(){int x,y;read(a),read(b);for(ri i=0;i<=9;i++)f[1][i]=1;x=a;while(x){numa[++toa]=x%10;x=x/10;}x=b;while(x){numb[++tob]=x%10;x=x/10;}bool flag=1;for(ri i=2;i<=tob;i++)if(abs(numb[i]-numb[i-1])<2){flag=0;break;}for(ri i=2;i<=tob;i++){for(ri j=0;j<=9;j++){for(ri k=0;k<=9;k++){if(abs(k-j)>=2)f[i][j]+=f[i-1][k];}}}ll ans=0;ans+=flag;for(ri i=1;i<numb[tob];i++)ans+=f[tob][i];for(ri i=1;i<tob;i++){for(ri j=1;j<=9;j++)ans+=f[i][j];}for(ri i=tob-1;i>=1;i--){for(ri j=0;j<numb[i];j++){if(abs(j-numb[i+1])>=2)ans+=f[i][j];}if(abs(numb[i]-numb[i+1])<2)break;}for(ri i=1;i<numa[toa];i++)ans-=f[toa][i];for(ri i=1;i<toa;i++){for(ri j=1;j<=9;j++)ans-=f[i][j];}for(ri i=toa-1;i>=1;i--){for(ri j=0;j<numa[i];j++){if(abs(j-numa[i+1])>=2)ans-=f[i][j];}if(abs(numa[i]-numa[i+1])<2)break;}printf("%lld\n",ans);return 0;
}

转载于:https://www.cnblogs.com/Rye-Catcher/p/9843805.html

luogu2657-Windy数题解--数位DP相关推荐

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

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

  2. uestc 250 windy数(数位dp)

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

  3. 【BZOJ1026】windy数,数位DP

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

  4. bzoj 1026: [SCOI2009]windy数(数位dp)

    1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 7688  Solved: 3470 [Submit][S ...

  5. 1083 Windy数(数位dp)

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

  6. windy数(数位dp)

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

  7. P2657 [SCOI2009] windy 数(数位DP)

    题目链接:[SCOI2009] windy 数 - 洛谷 这是一道需要考虑前导0的数位DP题,为什么需要考虑前导0呢?其实原因很简单,因为有条件限制我们相邻两个数的差,所以我们在进行数位DP时必须把前 ...

  8. [BZOJ 1026] [SCOI 2009] Windy数 【数位DP】

    题目链接:BZOJ - 1026 题目分析 这道题是一道数位DP的基础题,对于完全不会数位DP的我来说也是难题.. 对于询问 [a,b] 的区间的答案,我们对询问进行差分,求 [0,b] - [0,a ...

  9. BZOJ1026 || 洛谷P2657 [SCOI2009]windy数【数位DP】

    Time Limit: 1 Sec Memory Limit: 162 MB Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. ...

最新文章

  1. 看你的样子对Vue研究挺深的,我司招Vue,五险一金有兴趣吗?
  2. 1.FPGA开发软件安装——Vivado
  3. ABAP设置输入焦点和表格控件行数的注意事项
  4. keras从入门到放弃(十三)卷积神经网络处理手写数字识别
  5. 《EDIUS 6.5快刀手高效剪辑技法》 即将上市
  6. react-redux图解_如何将React连接到Redux —图解指南
  7. 上下文信息 RpcContext
  8. 数论之勾股数组(毕达哥拉斯三元组)
  9. 麟龙指标通达信指标公式源码_麟龙指标套三 麟龙特色指标 通达信主图+副图指标 贴图...
  10. SuperMap 三维模型数据制作
  11. 七月阅读:《刘慈欣科幻短篇小说集Ⅰ》笔记
  12. UAC 管理员权限 程序 防止弹窗的四种解决办法
  13. 基于android的理财软件,基于Android的理财系统APP的设计
  14. Instance Segmentation by Jointly Optimizing Spatial Embeddings and Clustering Bandwidth【论文解读】
  15. 走出误区,老杨命运发生了转折
  16. 100个世界上鲜为人知的奇闻怪事小知识(转)
  17. 搜救犬都负责什么工作
  18. 为什么空集是集合的子集_空集为什么是任何集合的子集和非任何空集的真子集呢...
  19. 【JAVA程序设计】(C00046)javaweb图书借阅管理系统
  20. IE和chrom兼容性分析(持续更新)

热门文章

  1. Ubuntu 22.04 为 Jellyfin 配置代理
  2. 子桓说:学几招商业套路,以后用的上!
  3. 以太坊挖矿源码:ethash算法
  4. 内存不能为READ的原因
  5. 机器学习(6)——周志华
  6. C语言期末程序设计(高铁客运订票系统)
  7. 阿里数据库十年变迁,那些你不知道的二三事
  8. 小程序开发.微信小程序.组件.视图容器
  9. 实现窗口动漫人物眼睛跟随鼠标滚动
  10. Django simpleui实战web平台开发