uva11038_How Many O's?_数位DP

问m~n之间的数中共有多少个0,过程稍稍麻烦了一些,半天的时间才搞定。

直接上码吧

/*************************************************************************

    > File Name: 11038_数位DP.cpp

    > Author: Chierush

    > Mail: [email protected] 

    > Created Time: 2013年06月16日 星期日 16时13分54秒

 ************************************************************************/



#include <iostream>

#include <cstring>

#include <cstdlib>

#include <set>

#include <cstdio>

#include <string>

#include <vector>

#include <map>

#include <cmath>

#include <algorithm>



#define LL long long

#define LLU unsigned long long



using namespace std;



LL g(char *s)

{

    LL ans=0;

    for (int i=1;i<strlen(s);++i)

        ans=ans*10+s[i]-'0';

    return ++ans;

}



LL f[12],Count[12],sum[12],sbit[12];

char s[12];



LL dp(LL n)

{

    if (n<0) return 0;

    if (n<10) return 1;

    LL ans=0;

    sprintf(s,"%lld",n);

    ans+=sum[strlen(s)-1]+(s[0]-'1')*(sum[strlen(s)-1]+sbit[strlen(s)-1]);

    //printf("---%lld\n",ans);

    for (int i=1;i<strlen(s)-1;++i)

        if (s[i]>'0')

        {

            ans+=(sum[strlen(s)-i-1]+sbit[strlen(s)-i-1])*(s[i]-'1');

            ans+=Count[strlen(s)-i-1]+sum[strlen(s)-i-1]+sbit[strlen(s)-i-1];

        }

        else

            ans+=g(s+i);

    return ++ans;

}



int main()

{

    Count[1]=10;

    for (int i=2;i<=10;++i)

        Count[i]=Count[i-1]*10;

    for (int i=2;i<=10;++i)

        sbit[i]=Count[i-1]+sbit[i-1];

    sum[1]=f[1]=1;

    for (int i=2;i<=10;++i)

        f[i]=9*(sum[i-1]+sbit[i-1]),sum[i]=sum[i-1]+f[i];

    LL n,m;

    //printf("%lld\n",dp(500));

    while (scanf("%lld%lld",&m,&n) && m>=0)

        printf("%lld\n",dp(n)-dp(m-1));

    return 0;

}

  

你可能感兴趣的:(uva)