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 。

  • 相关阅读:
    CLRS2e读书笔记—Chapter10
    CLRS2e读书笔记—Chapter6
    CLRS2e读书笔记—Chapter34 & Appendix A,B
    CLRS2e读书笔记—Chapter8
    CLRS2e读书笔记—Chapter5 & Appendix C
    CLRS2e读书笔记—Chapter7
    Haskell学习笔记<三>
    屏幕一直亮的问题
    对CCLabelTTF进行自动换行,显示打字效果
    XCODE 4.2打包发布
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7898217.html
Copyright © 2011-2022 走看看