P4999トラブル(GUI)人(チュー)数学の宿題

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で
面白いマニュアル

おすすめ

転載: www.cnblogs.com/lcez56jsy/p/11482850.html