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; }