zoukankan      html  css  js  c++  java
  • BZOJ_1026_[SCOI2009]_windy数_(数位dp)

    描述


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

    windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
    在A和B之间,包括A和B,总共有多少个windy数?

    分析


    我们用(dp[i][j])表示以(j)开头的(i)为数中windy数一共有多少.

    然后用(solve(x))求出([1,x])内的windy数一共有多少,步骤如下:

    1.将(x)一位一位拆开,共(cnt)位,第(i)位为(num[i]).

    2.统计以(1,2,3,...,9)开头的(i)位数中共有多少windy数,其中(i<cnt).

    3.对于(cnt)位数,显然我们是不能把(dp[cnt][num[cnt])加进去的.比如(x=5786),以(5)开头的(4)位数没有完全包含,所以只能从(dp[cnt][1])计算到(dp[cnt][num[cnt]-1]),然后对于第(cnt)位为(num[cnt])的,就到(cnt-1)位去计算.(相当于数钱,一共5786,数到4999,不能直接数5999,对于>=5000的,要从百位开始数了).

    4.依次往后退,但是注意,当(num[i])与(num[i+1])相差不到(2)的话,对于第(i)位是(num[i])的情况就不需要考虑了,也就不用继续下去了.

    5.由于第(cnt)位不能取(0),而只有最后一位可以去(num[i]),比较特殊,所以需要单独处理,可以特判一位数的情况,确保至少有最高位和最低位两个不同的位.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef long long ll;
     5 int num[11];
     6 ll dp[11][11];
     7 ll a,b;
     8 inline ll read(ll &x){ x=0;ll k=-1;char c;for(c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')k=-1;for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';return x*k; }
     9 ll solve(int x){
    10     if(x<10) return x;
    11     ll ans=0; int cnt=0;
    12     while(x) num[++cnt]=x%10, x/=10;
    13     for(int i=1;i<cnt;i++) ans+=dp[i][10]-dp[i][0];
    14     for(int i=1;i<num[cnt];i++) ans+=dp[cnt][i];
    15     for(int i=cnt-1;i;i--){
    16         for(int j=0;j<num[i];j++)if(abs(num[i+1]-j)>1)
    17         ans+=dp[i][j];
    18         if(i==1&&abs(num[i+1]-num[i])>1) ans++;
    19         if(abs(num[i+1]-num[i])<=1) break;
    20     }
    21     return ans;
    22 }
    23 int main(){
    24     read(a); read(b);
    25     for(int i=0;i<10;i++) dp[1][i]=1;
    26     dp[1][10]=10;
    27     for(int i=2;i<=10;i++)for(int j=0;j<10;j++){
    28         for(int k=0;k<10;k++)if(abs(j-k)>1) 
    29             dp[i][j]+=dp[i-1][k];
    30         dp[i][10]+=dp[i][j];
    31     }
    32     printf("%lld
    ",solve(b)-solve(a-1));
    33 }
    View Code

    1026: [SCOI2009]windy数

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 5441  Solved: 2450
    [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

  • 相关阅读:
    .Net环境下的缓存技术介绍
    JavaScript 全局对象
    JavaScript escape() 函数
    实现DIV拖动
    巧用Ajax的beforeSend 提高用户体验
    js中ie8下不识别indexOf的解决办法
    页面弹窗效果HTML
    让html页面中的文字不可选中
    MVC路由规则
    C# Math.Round
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5598873.html
Copyright © 2011-2022 走看看