luogu3413 Meng number

https://www.luogu.org/problem/P3413

Digital dp title

Count the number of direct Meng is not easy, but directly count the number of non-Meng easier

A non-sprouting for any number as long as a $ i $, $ num [i]! = Num [i + 1] and [i] num! = Num [i + 2] $

Note judge leading 0

 

#include<bits/stdc++.h>
using namespace std;
const int N=1005,mod=1e9+7;
long long f[N][10][10][2][2],ans,A,B;
char ch[2][N];
int num[N],cnt;
long long dfs(int pos,int ls2,int ls1,bool lead,bool limit)
{
    if(~f[pos][ls2][ls1][lead][limit]) return f[pos][ls2][ls1][lead][limit];
    int r=limit?num[pos]:9;
    long long ret=0;
    for(int i=0;i<=r;++i)
    {
        if(pos==1 && ((i!=ls1 && i!=ls2) || (i==0 && lead))) ++ret;
        if(pos==1) continue;
        if(i!=ls2 && i!=ls1)
            ret=(ret+dfs(pos-1,ls1,i,(ls1==0)&lead,(i==num[pos])&limit))%mod;
        if(lead && i==0)
            ret=(ret+dfs(pos-1,ls1,0,(ls1==0)&lead,(i==num[pos])&limit))%mod;
    }
    f[pos][ls2][ls1][lead][limit]=ret;
    //cout<<pos<<" "<<ls2<<" "<<ls1<<" "<<lead<<" "<<limit<<" "<<ret<<endl;
    return ret;
}
void solve(bool on)
{
    cnt=strlen(ch[on]+1);
    for(int i=1;i<=cnt;++i) num[i]=ch[on][cnt-i+1]-'0';
    memset(f,-1,sizeof(f));
    if(on) ans=(dfs(cnt,0,0,1,1)-ans+mod)%mod;
    else ans=dfs(cnt,0,0,1,1);
}
int main()
{
    scanf("%s%s",ch[0]+1,ch[1]+1);
    solve(0); solve(1);
    bool flag=0;
    for(int i=1;i<=strlen(ch[0]+1);++i)
    {
        if(ch[0][i]==ch[0][i+1]) flag=1;
        if(ch[0][i]==ch[0][i+2]) flag=1;
        A=(A*10+ch[0][i]-'0')%mod;
    }
    for(int i=1;i<=strlen(ch[1]+1);++i)
        B=(B*10+ch[1][i]-'0')%mod;
    //cout<<"ans:"<<ans<<endl;
    if(flag) printf("%lld",((B-A-ans+1)%mod+mod)%mod);
    else printf("%lld",((B-A-ans)%mod+mod)%mod);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/w19567/p/11315958.html