不要666------数位dp

本文深入解析数位动态规划(DP)的核心概念与应用技巧,通过实例展示如何利用记忆化搜索提高算法效率,解决复杂计数问题。文章详细解释了Dp[pos][num1][num2]状态转移方程,以及如何在限定条件下求解满足特定条件的数字组合数量与总和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题
当时都没有来得及去想这题,后面补提一直报错,看了下大牛们的操作才恍然大悟。
一道典型的数位dp,记忆化处理加快效率。
Dp【pos】【num1】【num2】,其中,pos存剩下的位数,num1存在已剩下位数中(使用的前提没有上值的限制),满足num1和num2状态的答案(根本不需要去考虑前几个位数是否一致,只要考虑它们在此时的num1和num2的状态一致即可),
ans.sum=(ans.sum+temp.sum+i*bit[ps]temp.cnt%mod)%mod;,这里乘temp.cnt的意思是,在以当前的i为该位,那么后面有多少个满足与6无关的数字,有多少个,加多少个ibit【ps】

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mod=1e9+7;
struct node{
    ll cnt,sum;   // cnt存数量,sum存答案
    node(ll _cnt,ll _sum):cnt(_cnt),sum(_sum){
    }
    node():cnt(-1),sum(0){
    }
}dp[20][10][10];
ll bit[21],pos[20];    // 这里bit数组大小一定要21,20就错了,我也不知道为什么,明明全部小于1e18的
 
node dfs(int ps,int num1,int num2,int limit){
    if( ps==-1 ){
        if( num1==0 || num2==0 )
            return node(0,0);
        else
            return node(1,0);
    }
    if( limit!=1 && dp[ps][num1][num2].cnt!=-1 )
        return dp[ps][num1][num2];    // 若以前走过,那么就直接return,不用再次走一遍浪费时间
    int up=limit?pos[ps]:9;
    node ans;
    ans.cnt=0;
    for( int i=0 ; i<=up ; i++ ){
        if( i==6 )
            continue;
        node temp=dfs(ps-1,(num1+i)%6,(num2*10+i)%6,i==up&&limit);
        ans.cnt=(ans.cnt+temp.cnt)%mod;
        ans.sum=(ans.sum+temp.sum+i*bit[ps]*temp.cnt%mod)%mod;   // 一个一个加上去
    }
    if( limit!=1 )
        dp[ps][num1][num2]=ans;
    return ans;
}
 
ll solve(ll k){
    int len=0;
    while( k ){
        pos[len++]=k%10;
        k/=10;
    }
    return dfs(len-1,0,0,1).sum;
}
 
int main()
{
    //freopen("input.txt","r",stdin);
    bit[0]=1;
    ll l,r;
    for( int i=1 ; i<=20 ; i++ )
        bit[i]=bit[i-1]*10%mod;
    while( ~scanf("%lld %lld",&l,&r) ){
        printf("%lld\n",(solve(r)-solve(l-1)+mod)%mod);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值