hdu 2089 不要62 (数位dp)

题意:http://acm.hdu.edu.cn/showproblem.php?pid=2089

思路:首先初始化预处理dp[i][j] 及i位数当前位为j时 即 0到 i * 10^j 符合条件的数

        然后求出 fun(r+1)-fun(l)

        fun从大的位数开始计算

 

#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

int dp[20][20];

int a[20];

int init()

{

    int i,j,k;  //i : i位数  j:当前位为j   k:后一位为 k

    memset(dp,0,sizeof(dp));

    dp[0][0]=1;

   for(i=1;i<=7;i++)

   {

       for(j=0;j<10;j++)

       {

               for(k=0;k<10;k++)

              {

                   if(j==4||(j==6&&k==2)) continue;

                       dp[i][j]+=dp[i-1][k];

              }

       }

   }

}

int fun(int n)

{

    int ans=0;

    int len=1;

    int i,j,k;

    while(n)

    {

        a[len++]=n%10;

        n/=10;

    }

    a[len]=0;

    for(i=len-1;i>=1;i--)

    {

        for(j=0;j<a[i];j++)

        {

            if(j==4||(a[i+1]==6&&j==2)) continue;

            ans+=dp[i][j];

        }

        if(a[i]==4||a[i+1]==6&&a[i]==2) break;

    }

    return ans;

}

int main()

{

    int l,r;

    int i,j,k;

    while(scanf("%d%d",&l,&r)!=EOF)

    {

       if(l==0&&r==0) break;

       init();

       printf("%d\n",fun(r+1)-fun(l));

    }

    return 0;

}

  

你可能感兴趣的:(HDU)