zoukankan      html  css  js  c++  java
  • BZOJ 1026:windy数(数位DP)

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

    1026: [SCOI2009]windy数

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

    题意比较简单,这里有点蛋疼的是第一个样例我一开始看不懂,然后问了别人才知道例如第一个样例 1 10 的答案是 1 - 9。
    所以可能最高位如果前面都是零的话,那么它可以任意选择一个数(0 - 位上限)
    如果最高位前面不全都是零的话,那么它就要按照规则即和前一位相差2来取。
    还是太弱了。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 using namespace std;
     7 #define N 35
     8 //long long dp[N][15][2][2];
     9 long long dp[N][15][2];
    10 int bit[N];
    11 /*
    12 zero判断前面是不是全都是 0,
    13 1的话说明前面没有前导零,有值
    14 0的话说明前面没有值,都是零
    15 */
    16 //我一开始的写法
    17 //long long dfs(int pos, int pre, int  st, int zero, int flag)
    18 //{
    19 //    if( !pos ) return st;
    20 //    if( zero && !flag && dp[pos][pre][st][zero] != -1 ) return dp[pos][pre][st][zero];
    21 //
    22 //    long long ans = 0;
    23 //    int u = flag ? bit[pos] : 9;
    24 //
    25 //    if( zero == 0 ){
    26 //        for(int i = 0; i <= u; i++){
    27 //            ans += dfs(pos - 1, i, i == 0 ? 0 : 1, i == 0 ? 0 : 1, flag && i==u);
    28 //        }
    29 //    }
    30 //    else{
    31 //        for(int i = 0; i <= u; i++){
    32 //            if( abs(pre - i) >= 2 ){
    33 //                ans += dfs(pos - 1, i, 1, 1, flag && i==u);
    34 //            }
    35 //        }
    36 //    }
    37 //
    38 //    if( zero && !flag ) dp[pos][pre][st][zero] = ans;
    39 //    return ans;
    40 //}
    41 //看了别人的写法,简化了很多
    42 long long dfs(int pos, int pre, int zero, int flag)
    43 {
    44     if( !pos ) return 1;
    45     if( zero && !flag && ~dp[pos][pre][zero] ) return dp[pos][pre][zero];
    46 
    47     long long ans = 0;
    48     int u = flag ? bit[pos] : 9;
    49 
    50     for(int i = 0; i <= u; i++){
    51         if( !zero || abs(pre - i) >= 2 )
    52 /*
    53 例如第一个样例 1 10 的答案是 1 - 9
    54 所以可能最高位如果前面都是零的话,那么它可以任意选择一个数(0 - u)
    55 如果最高位前面不行全都是零的话,那么它就要按照规则即和前一位相差2来取
    56 这一题的没有前导零还有第一个样例搞得我很迷糊。我还是太弱了
    57 */
    58             ans += dfs(pos - 1, i, i || zero, flag && i==u);
    59     }
    60     if( !flag ) dp[pos][pre][zero] = ans;
    61     return ans;
    62 }
    63 
    64 long long solve(long long x)
    65 {
    66     int l = 0;
    67     while(x>0){
    68         bit[++l] = x % 10;
    69         x /= 10;
    70     }
    71 //    return dfs(l, 0, 0, 0, 1);
    72     return dfs(l, 0, 0, 1);
    73 }
    74 
    75 int main()
    76 {
    77     long long a, b;
    78     cin >> a >> b;
    79     memset(dp, -1, sizeof(dp));
    80     if(a > b) swap(a, b);
    81 //    cout << solve(b) <<  "  " << solve(a-1) << endl;
    82     cout << solve(b) - solve(a-1) << endl;
    83     return 0;
    84 }
  • 相关阅读:
    css随笔7
    css随笔6
    css随笔5
    *css随笔4
    css3随笔3
    css随笔2
    css随笔1
    HTML总结
    HTML随笔2
    消息转发原理
  • 原文地址:https://www.cnblogs.com/fightfordream/p/5680744.html
Copyright © 2011-2022 走看看