您的位置:首页 > 其它

uva11038_How Many O's?_数位DP

2013-06-17 00:32 302 查看
问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;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: