1026: [SCOI2009]windy数

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 8203  Solved: 3687
[Submit][Status][Discuss]

Description

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

Input

  包含两个整数,A B。

Output

  一个整数

Sample Input

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

Sample Output

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

HINT

【数据规模和约定】

100%的数据,满足 1 <= A <= B <= 2000000000 。

 题解

第一次做数位dp的题(从1662滚过来)

这道题也算是挺裸的一道数位dp 只需要记录上一位就可以判断是否合法

状态转移方程:令f[i][j]表示前i位,最高位为j的方案数

f[i][j]=sum(f[i-1][k]) if(k-j>=2)

代码大体是照着 http://www.cnblogs.com/zbtrs/p/6105338.html 打的 我觉得讲的非常棒

对于几个可能不太好理解的位置我加了一点注释

/**************************************************************
    Problem: 1026
    User: a799091501
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:1292 kb
****************************************************************/
 
#pragma GCC optimize("O2")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<limits.h>
#include<ctime>
#define N 100001
typedef long long ll;
const int inf=999999999;
const int maxn=2017;
using namespace std;
ll f[20][20],num[20];
inline int read()
{
    int f=1,x=0;char ch=getchar();
    while(ch>'9'|ch<'0')
    {
        if(ch=='-')
        f=-1;
        ch=getchar();
    }
    while(ch<='9'&&ch>='0')
    {
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }
    return f*x;
}
void init()
{
    memset(f,0,sizeof(f));
    for(int i=0;i<=9;i++)
    f[1][i]=1;//第一位所有数都是windy数
    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]; //第i位最高位为j的状态可以从每一个符合条件的i-1位最高位为k转移而来    
}
ll solve(ll x)
{
    memset(num,0,sizeof(num));
    if(x==0)return 0;
    ll pos=0,ans=0;
    while(x)
    {
        num[++pos]=x%10;
        x/=10;
    }
    for(int i=1;i<pos;i++)
    for(int j=1;j<=9;j++)//不含前导零,因此从1开始枚举
    ans+=f[i][j];
    for(int i=1;i<num[pos];i++)
    ans+=f[pos][i];
    for(int i=pos-1;i>=1;i--)
    {
        for(int j=0;j<num[i];j++)//枚举最高位的所有状态
        if(abs(j-num[i+1])>=2)//上一位
        ans+=f[i][j];
        if(abs(num[i+1]-num[i])<2)break;//后面的答案不可能有贡献,跳出
        if(i==1)ans+=1;
    }
    return ans;
}
int main()
{
    int a=read(),b=read();
    init();
    cout<<solve(b)-solve(a-1);
}

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】[SCOI2009]windy数 数位dp

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

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

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

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

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

  10. P2657 [SCOI2009]windy数 数位dp

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

随机推荐

  1. Leetcode刷题第004天

    class Solution { public: int findKthLargest(vector<int>& nums, int k) { , nums.size()-, k) ...

  2. 有道词典Linux版下载安装

    http://cidian.youdao.com/index-linux.html Ubuntu http://codown.youdao.com/cidian/linux/youdao-dict_1 ...

  3. VS2015 生成事件 命令参数

    来源:https://stackoverflow.com/questions/11001822/copy-files-from-one-project-to-another-using-post-bu ...

  4. k8s 1.12.6版的kubeadm默认配置文件

    这个对于提高安装配置的便捷性,相当有帮助. 命令如下: kubeadm config print-default 输出如下: apiEndpoint: advertiseAddress: 1.2.3. ...

  5. 长短时记忆网络LSTM和条件随机场crf

    LSTM 原理 CRF 原理 给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型.假设输出随机变量构成马尔科夫随机场(概率无向图模型)在标注问题应用中,简化成线性链条件随机场,对数线性判别 ...

  6. libsecp256k1 与 openssl ecdsa

    1. 历史 区块链节点在接收到的用户发送的交易时,首先会验证交易所涉及utxo的可用性.方法是验证用户签名的合法性,涉及的签名算法就是secp256k1,一种椭圆曲线加密算法. 长期以来,实现了该算法 ...

  7. spark操作Kudu之写 - 使用DataFrame API

    在通过DataFrame API编写时,目前只支持一种模式“append”.尚未实现的“覆盖”模式 import org.apache.kudu.spark.kudu._ import org.apa ...

  8. jenkins(1): jenkins安装以及从gitlab拉取代码

    1. gitlab前面已经写过了,自己去参考 https://www.cnblogs.com/yitianyouyitian/p/9214940.html 2. jenkins安装 2.1 jdk 安 ...

  9. BZOJ4003 [JLOI2015]城池攻占 左偏树 可并堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4003 题意概括 题意有点复杂,直接放原题了. 小铭铭最近获得了一副新的桌游,游戏中需要用 m 个骑 ...

  10. 12306登录爬虫 session版本

    import requests import re import base64 # 定义session headers = { 'User-Agent':'Mozilla/5.0 (Windows N ...