zoukankan      html  css  js  c++  java
  • bzoj1026: [SCOI2009]windy数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1026

    数位DP

    如果前一位填的是0,

    0是前导0,下一位可以随便填

    0不是前导0,下一位不能填1

    为避免这种情况

    枚举位数,强制不出现前导0

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    int dp[12][12];
    
    int a[11];
    
    int LEN;
    
    int dfs(int dep,int num,bool lim)
    {
        if(!lim && dp[dep][num]!=-1) return dp[dep][num];
        if(!dep) return 1;
        int up= lim ? a[dep] : 9,tmp=0; 
        for(int i=0;i<=up;++i)
        {
            if(dep==LEN && !i) continue;
            if(abs(i-num)<2) continue;
            tmp+=dfs(dep-1,i,lim && i==up);
        }
        if(!lim) dp[dep][num]=tmp;
        return tmp;
    }
    
    int solve(int n)
    {
        if(!n) return 0;
        int len=0;
        while(n)
        {
            a[++len]=n%10;
            n/=10;
        }
        int sum=0;
        for(int i=1;i<len;++i) 
        {
            LEN=i;
            sum+=dfs(i,11,0);
        }
        LEN=len; 
        sum+=dfs(len,11,1);
        return sum;
    }
    
    int main()
    {
        int a,b;
        scanf("%d%d",&a,&b);
        memset(dp,-1,sizeof(dp));
        printf("%d
    ",solve(b)-solve(a-1));
    }
    View Code

    或者是记录有无前导零这个状态

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    int dp[12][12][2];
    
    int a[11];
    
    int LEN;
    
    int dfs(int dep,int num,bool lim,bool zero)
    {
        if(!lim && dp[dep][num][zero]!=-1) return dp[dep][num][zero];
        if(!dep) return !zero;
        int up= lim ? a[dep] : 9,tmp=0; 
        for(int i=0;i<=up;++i)
        {
            if(abs(i-num)<2 && !zero) continue;
            tmp+=dfs(dep-1,i,lim && i==up,zero && !i);
        }
        if(!lim) dp[dep][num][zero]=tmp;
        return tmp;
    }
    
    int solve(int n)
    {
        if(!n) return 0;
        int len=0;
        while(n)
        {
            a[++len]=n%10;
            n/=10;
        }
        return dfs(len,11,1,1);
    }
    
    int main()
    {
        int a,b;
        scanf("%d%d",&a,&b);
        memset(dp,-1,sizeof(dp));
        printf("%d
    ",solve(b)-solve(a-1));
    }
    View Code

    1026: [SCOI2009]windy数

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 8771  Solved: 3959
    [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 。

  • 相关阅读:
    Spark Streaming源码解读之Receiver生成全生命周期彻底研究和思考
    linux 修改时间时区,修改语言
    远程链接mysql error 2003
    Android NDK r10c 编译boost 1.55 (使用Cygwin)
    linux上cocos2dx Android打包环境
    linux上cocos2dx 环境配置
    linux, windows编译安装 boost库 (boost 1.56)
    编译安装 gcc 4.8.3
    vim配置添加python
    mvn设置
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7898217.html
Copyright © 2011-2022 走看看