zoukankan      html  css  js  c++  java
  • BZOJ 1026 [SCOI2009]windy数

    1026: [SCOI2009]windy数

    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 。


      数位DP,统计类问题。上下界均在int范围内,故不必用long long(这样的判断是很有必要的)。

      包括A,B。我们通常可以方便算出1~n-1的范围内符合条件的总数。所以,只需要1~(A+1)-1减去1~B-1即可。

      DP方程很好写,但统计确实需要分段。本人最开始想少做些事情,但JIJI了(否则极复杂),也算是刷新了对数位DP的理解。

    • 1~9,10~99,100~999,1000~9999……(先把位数为1至cnt-1计入)
    • 100..0~(x-1)99..9(确定最高位 )
    • x00..0~x(y-1)9..9,xy0..0~xy(z-1)9..9,……,(高位到低位,如果高位已经出现非法,直接退出)
     1 /**************************************************************
     2     Problem: 1026
     3     User: Doggu
     4     Language: C++
     5     Result: Accepted
     6     Time:0 ms
     7     Memory:820 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 const int N = 15;
    12 int a, b, f[N][10], ans;
    13 int abs(int a) {return a>0?a:-a;}
    14 int DP(int k,int i) { 
    15     if(f[k][i]) return f[k][i];
    16     if(k==1) return  f[k][i]=1;
    17     for( int j = 0; j <= 9; j++ ) if(abs(i-j)>=2) f[k][i]+=DP(k-1,j);
    18     return f[k][i];
    19 }
    20 void CAL(int num,int delta) {//cal 0~num-1
    21     int digit[N], cnt = 0;
    22     while(num) digit[++cnt]=num%10,num/=10;
    23     for( int bit = 1; bit < cnt; bit++ )  //先把长度为1至cnt-1计入  
    24         for( int i = 1; i < 10; i++ )
    25             ans += delta*DP(bit,i);
    26     for( int i = 1; i < digit[cnt]; i++ )   //确定最高位  
    27         ans += delta*DP(cnt,i);
    28     for( int bit = cnt-1; bit >= 1; bit-- ) {
    29         for( int i = 0; i < digit[bit]; i++ ) if(bit==cnt||abs(i-digit[bit+1])>=2) ans += delta*DP(bit,i);
    30         if(abs(digit[bit]-digit[bit+1])<2) break;//如果高位已经出现非法,直接退出
    31     }
    32 }
    33 int main() {
    34     scanf( "%d%d", &a, &b );
    35     CAL(b+1,+1);
    36     CAL(a,-1);
    37     printf("%d
    ",ans);
    38     return 0;
    数位DP
  • 相关阅读:
    Oracle 推出 ODAC for Entity Framework 和 LINQ to Entities Beta版
    Entity Framework Feature CTP 5系列文章
    MonoDroid相关资源
    MSDN杂志上的Windows Phone相关文章
    微软学Android Market推出 Web Windows Phone Marketplace
    使用 Visual Studio Agent 2010 进行负载压力测试的安装指南
    MonoMac 1.0正式发布
    Shawn Wildermuth的《Architecting WP7 》系列文章
    使用.NET Mobile API即51Degrees.mobi检测UserAgent
    MongoDB 客户端 MongoVue
  • 原文地址:https://www.cnblogs.com/Doggu/p/bzoj1026.html
Copyright © 2011-2022 走看看