码迷,mamicode.com
首页 > Windows程序 > 详细

BZOJ 1026: [SCOI2009]windy数

时间:2017-12-27 22:33:41      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:max   post   数字   ble   php   zoj   lin   efi   div   

二次联通门 : BZOJ 1026: [SCOI2009]windy数

 

 

 

/*
    BZOJ 1026: [SCOI2009]windy数

    水题开心
    数位dp
    f[i][j]表示一个i位的数字的第i位是j的数字有几个

    设 s (x)为[0,x)的答案
    怎么求s(x)?
    设x有t位,我们先找到所有t - 1的符合题意的数
    然后从高到低一位一位得确定为原数字x对应位上的数字
    在此基础上累计方案数就好了
    就能求出[0,x)的答案了
    然后s (M + 1) - s (N)即可
*/
#include <cstdio>

#define rg register
#define Max 20
int f[Max][Max], d[Max];
inline int abs (int x) { return x < 0 ? -x : x; }
int Calc (int x)
{
    int c = 0, res = 0; rg int i, j, k;
    for (; x; d[++ c] = x % 10, x /= 10);
    for (i = 1; i < c; ++ i)
        for (j = 1; j <= 9; ++ j) res += f[i][j];
    for (i = c; i; -- i)
    {
        for (j = (i == c); j < d[i]; ++ j)
            if (i == c || abs (j - d[i + 1]) >= 2)
                res += f[i][j];
        if (i < c && abs (d[i + 1] - d[i]) < 2) break;
    }
    return res;
}
int main (int argc, char *argv[])
{
    rg int i, j, k;
    for (i = 0; i <= 9; ++ i) f[1][i] = 1;
    for (i = 1; i <= 10; ++ i)
        for (j = 0; j <= 9; ++ j)
        {
            for (k = 0; k <= j - 2; ++ k) f[i + 1][k] += f[i][j];
            for (k = j + 2; k <= 9; ++ k) f[i + 1][k] += f[i][j];
        }
    int N, M;
    scanf ("%d%d", &N, &M);
    printf ("%d", Calc (M + 1) - Calc (N));

    return 0;
}

 

BZOJ 1026: [SCOI2009]windy数

标签:max   post   数字   ble   php   zoj   lin   efi   div   

原文地址:https://www.cnblogs.com/ZlycerQan/p/8127816.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!