• 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 。

  • 相关阅读:
    文件上传按钮样式定制
    消除2个按钮之间1px细节引起的冲突
    css 实用代码汇总
    除掉inline-block 间距
    SQL Server 创建索引的 5 种方法
    百度API从经纬度坐标到地址的转换服务
    百度地图API简单应用——1.根据地址查询经纬度
    极光API推送 (v3 版本)
    简单快捷地测试 JPush API
    使用极光推送(www.jpush.cn)向安卓手机推送消息【服务端向客户端主送推送】C#语言
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7898217.html
Copyright © 2020-2023  润新知