uva11038_How Many O's?_数位DP
问m~n之间的数中共有多少个0,过程稍稍麻烦了一些,半天的时间才搞定。
直接上码吧
/*************************************************************************
> File Name: 11038_数位DP.cpp
> Author: Chierush
> Mail: qinxiaojie1@gmail.com
> 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;
}

浙公网安备 33010602011771号