码迷,mamicode.com
首页 > 其他好文 > 详细

UESTC 250 数位dp(数字相位数之间的差值不小于2)

时间:2015-02-17 12:57:01      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.uestc.edu.cn/#/problem/show/250

windy定义了一种windy数。

不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。

windy想知道,在AB之间,包括AB,总共有多少个windy数?

Input

包含两个整数,A B

满足 1AB2000000000 .

Output

Sample input and output

Sample Input Sample Output
1 10
9

Source

Windy

/**
UESTC 250  数位dp(数字相位数之间的差值不小于2)
题目大意:求给定区间内的数字有多少满足一个数字的不同位数的数字之差不小于2
解题思路:数位dp,dp[i][j]表示i位数,以j开头满足条件的个数。将n分解入len数组,然后先统计位数小于len的个数(不能统计以0开头的),
           再然后统计位数正好为len的个数。最后不要忘了考虑n本身
*/
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;

LL n,m,dp[20][15];
int abs(int x)
{
    if(x<0)return -x;
    return x;
}

void init()
{
    memset(dp,0,sizeof(dp));
    for(int i=0; i<10; i++)
    {
        dp[1][i]=1;
    }
    for(int i=2; i<=10; i++)
    {
        for(int j=0; j<10; j++)
        {
            for(int k=0; k<=j-2; k++)
            {
                dp[i][j]+=dp[i-1][k];
            }
            for(int k=j+2; k<10; k++)
            {
                dp[i][j]+=dp[i-1][k];
            }
        }
    }
}

int bit[20];

LL solve(LL n)
{
    if(n==0)return 0;
    int len=0;
    LL ans=0;
    while(n)
    {
        bit[++len]=n%10;
        n/=10;
    }
    bit[len+1]=-10;
    /**
     for(int i=1;i<=len;i++)
     {
         printf("%d ",bit[i]);
     }
     printf("\n");*/
    for(int i=1; i<len; i++)
    {
        for(int j=1; j<=9; j++)
        {
            ans+=dp[i][j];
        }
    }
    for(int i=1; i<bit[len]; i++)
    {
        ans+=dp[len][i];
    }
    int flag=1;
    for(int i=len-1; i>=1; i--)
    {
        for(int j=0; j<bit[i]; j++)
        {
            if(abs(bit[i+1]-j)>=2)
            {
                ans+=dp[i][j];
            }
        }
        if(abs(bit[i+1]-bit[i])<2)
        {
            flag=0;
            break;
        }
    }
    if(flag)ans++;
    ///  printf("ans=%lld\n",ans);
    return ans;
}

int main()
{
    init();
    while(~scanf("%lld%lld",&n,&m))
    {
        printf("%lld\n",solve(m)-solve(n-1));
    }
    return 0;
}
/**
1 13
13 15
20 24
*/



UESTC 250 数位dp(数字相位数之间的差值不小于2)

标签:

原文地址:http://blog.csdn.net/lvshubao1314/article/details/43865825

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