• 洛谷 P2657 [SCOI2009]windy数 解题报告


    P2657 [SCOI2009]windy数

    题目描述

    ( t{windy})定义了一种( t{windy})数。不含前导零且相邻两个数字之差至少为(2)的正整数被称为( t{windy})数。 ( t{windy})想知道,

    (A)(B)之间,包括(A)(B),总共有多少个( t{windy})数?

    输入输出格式

    输入格式:

    包含两个整数,(A) (B)

    输出格式:

    一个整数

    说明

    (100\%)的数据,满足 (1 le A le B le 2000000000)


    跟着咕咕日报了解了一下套路的数位( t{DP})的写法,发现之前自己( t{yy})的太( t{naive})

    思路是把前导(0)和高位限制放到记搜里面做参数直接解决。


    Code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    int dp[12][10],a[12];
    int dfs(int dep,int pre,int lead,int limit)//第几位,上一位的数字,前导0,高位是否有限制
    {
        if(~dp[dep][pre]&&!lead&&(!limit||!dep)) return dp[dep][pre];
        if(dep==0) return 0;
        int res=limit?a[dep]:9,ret=0;
        for(int i=0;i<=res;i++)
        {
            if(!lead&&abs(pre-i)<2) continue;
            if(!i&&lead) ret+=dfs(dep-1,i,lead,limit&i==res);
            //选0且有前导0,仍然有
            if(i&&lead) ret+=dfs(dep-1,i,!lead,limit&i==res);
            //选0且无前导0,没了
            if(!lead) ret+=dfs(dep-1,i,lead,limit&i==res);
            //无前导0
        }
        if(!limit&&!lead) dp[dep][pre]=ret;
        return ret;
    }
    int solve(int n)
    {
        if(!n) return 0;
        int cnt=0;
        for(int i=1;n;i++) a[++cnt]=n%10,n/=10;
        return dfs(cnt,0,1,1);
    }
    int main()
    {
        int a,b;
        memset(dp,-1,sizeof(dp));
        for(int i=0;i<=9;i++) dp[0][i]=1;
        scanf("%d%d",&a,&b);
        printf("%d
    ",solve(b)-solve(a-1));
        return 0;
    }
    

    2018.11.6

  • 相关阅读:
    TortoiseGit 合并主分支代码.pull request
    MVC EF 修改某些值
    MVC 提交表单
    MVC 统计之 自定义 列表
    MVC 起始页修改 区域
    asp.net C# MVC DropDownList
    asp.net C# MVC 提交表单后清空表单
    Python 线程启动的四种方式
    Git 命令的学习
    Node.js v10.1.0 Documentation
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9919231.html
Copyright © 2020-2023  润新知