luogu3413 萌数

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

数位dp题

直接算萌数不容易,但直接算非萌数比较容易

一个非萌数只要满足对于任意一位$i$,$num[i]!=num[i+1] 且 num[i]!=num[i+2]$

注意判断前导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;
}

 

转载于:https://www.cnblogs.com/w19567/p/11315958.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值