zoukankan      html  css  js  c++  java
  • bzoj 1026 [SCOI2009]windy数(数位DP)

    1026: [SCOI2009]windy数

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

    Source

    【思路】

           数位DP。

           设f[i][j]表示i位数且最高位为j的数中windy数的个数。则有转移式:

                  f[i][j]=sigma{ f[i-1][k] } ( | j-k |>=2 )

           统计:长度比len小的 -> 长度为len最高位比b[len]小的 -> 最高位为b[len],统计方法见代码。

           需要注意的是最后一项统计时,如果枚举过程中发现n不满足windy数则不再枚举,另外还需要注意n的计入与否。

    【代码】

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 
     5 const int N = 15;
     6 
     7 int f[N][N],b[N];
     8 
     9 void init() {
    10     for(int i=0;i<10;i++) f[1][i]=1;
    11     for(int i=2;i<=10;i++)
    12         for(int j=0;j<10;j++) {
    13             for(int k=0;k<=j-2;k++) f[i][j]+=f[i-1][k];
    14             for(int k=j+2;k<10;k++) f[i][j]+=f[i-1][k];
    15         }
    16 }
    17 int Fc(int n) {
    18     if(!n) return 0;
    19     int ans=0,len=0,flag=1;
    20     while(n)
    21         b[++len]=n%10 , n/=10;
    22     for(int i=1;i<len;i++)                                //统计所有长度小于 len 的
    23         for(int j=1;j<10;j++) ans += f[i][j];
    24     for(int j=1;j<b[len];j++) ans += f[len][j];                //长度为 len 最高位比 b[len] 小的
    25     for(int i=len-1;i;i--) {                            //统计最高位为 b[len] 的 
    26         for(int j=0;j<b[i];j++)
    27             if(abs(b[i+1]-j)>=2) ans += f[i][j];
    28         if(abs(b[i+1]-b[i])<2) {                        //n 不满足 不再统计后面的而且不计入 n 
    29             flag=0; break;
    30         }
    31     }
    32     if(flag) ans++;                                        //计入 n 
    33     return ans;
    34 }
    35 
    36 int main() {
    37     int n,m;
    38     init();
    39     scanf("%d%d",&n,&m);
    40     printf("%d",Fc(m)-Fc(n-1));
    41     return 0;
    42 }
  • 相关阅读:
    事务
    一、python 基础之基础语法
    二、python 中五种常用的数据类型
    三、python函数详解
    四、 面向对象(一)
    五、面向对象(二)——继承与重写
    六、异常处理、日志打印、文件操作
    scrapy(一):基础用法
    # scrapy(二):get请求
    scrapy(三):post请求
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5122644.html
Copyright © 2011-2022 走看看