D. Magic Numbers 数位dp

D. Magic Numbers
题意:明显数位dp,但是关键怎么写。
题解:直接看代码,更加清晰。这个dp方程我其实想到了,但是还是不够熟练地写出来。第一维是数位,第二维是mode m 的余数 , 第三维是当前数位限制。排除不合法的方案(continue掉的)。
ok函数就是检验b是否是个有效解。因为减答案的时候将b减掉了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod = 1e9+7;
int dp[2020][2020][2],n;
string x1,x2;
int b[3000];
int m,d;
ll dfs(int pos,int mo,int lim)
{
    if(pos==n+1) return (mo==0);
    if(dp[pos][mo][lim]!=-1) return dp[pos][mo][lim];
    int up = (lim==1)? b[pos] : 9;
    ll ans =  0;
    for(int i=0;i<=up;i++)
    {
        if(pos%2==0&&i!=d) continue;
        if(pos%2&&i==d) continue;
        int mo2 = (mo*10+i) % m;
        ans = ( ans% mod + dfs(pos+1,mo2,lim&&i==up) % mod ) % mod;
    }
    return dp[pos][mo][lim] = ans;
}
bool ok()
{
    int len = x1.length();
    int flag = 0,mo = 0;
    for(int i=0;i<len;i++)
    {
        if((i+1)%2==0&&b[i+1]!=d) {flag =1;break;}
        if((i+1)%2 && b[i+1]==d) {flag =1;break;}
        mo = (mo*10+b[i+1]) % m;
    }
    return (!flag)&&(mo==0);
}
int main()
{
     memset(dp,-1,sizeof(dp));cin>>m>>d;
     cin>>x1>>x2;
     n = x2.length();
     for(int i=0;i<n;i++) b[i+1] = x2[i] - '0';
     ll ans = 0;
     ans = dfs(1,0,1);
     n = x1.length();
     for(int i=0;i<n;i++) b[i+1] = x1[i] - '0';
     memset(dp,-1,sizeof(dp));
     if(ok()) ans ++;
     ans = ( ans - dfs(1,0,1) + mod ) % mod;
     cout<<ans<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值