P4399P4999
これは、3回の経験は宝のトピックでいます
我々はnに1を見つけることができ、1~9は、[i]はiが出現数の数であり、fが設けられ、複数回登場\(ANS = \和{F \ [I] \ CDOT I})
そして、物事を行うDPビット数であります
私たちは、あなたが境界線に到達することができたときに目標DPの数は、合計を返すときに、現在の要求の合計が発生した回数をカウントすることができます。先行ゼロノートの考慮事項
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf=214748364;
const ll mod=1000000007;//注意是1e9+7
inline ll read()
{
char ch=getchar();
ll x=0;bool f=0;
while(ch<'0'||ch>'9')
{
if(ch=='-')f=1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return f?-x:x;
}
ll l,r;
ll f[10],g[20][250],li[20];
int t;
void make(ll k)
{
t=0;
while(k)
{
li[++t]=k%10;
k/=10;
}
}
ll dfs(int now,int sum,int goal,bool lim,bool al)//al记录是否前面全是0
{
if(!now)return sum;
if(!al&&!lim&&g[now][sum]!=-1) return g[now][sum];
int up=lim?li[now]:9;
ll rtn=0;
for(int i=0;i<=up;i++)
{
rtn+=dfs(now-1,sum+((i||(!al))&&(i==goal)),goal,lim&&(i==up),al&&(!i));//这里sum的计算方式是在考虑goal是0的时候,排除前导零的影响(在另外那两倍经验那里也适用)
rtn=(rtn+mod)%mod;
}
if(!lim&&!al) g[now][sum]=rtn;
return rtn;
}
int main()
{
int fk=read();
while(fk--)
{
ll ans=0;
l=read();
r=read();
make(r);
for(int i=1;i<=9;i++)
memset(g,-1,sizeof(g)),f[i]=dfs(t,0,i,1,1);
if(l>1)
{
make(l-1);
for(int i=1;i<=9;i++)
memset(g,-1,sizeof(g)),f[i]-=dfs(t,0,i,1,1);
}
for(int i=1;i<=9;i++)
ans=(ans+((f[i]%mod)*i+mod)%mod+mod)%mod;
printf("%lld\n",ans);
}
}
二回の経験に加えて、P2602とP1239で
面白いマニュアル