hihocoder1033(数位DP)

作者: Alan66 | 来源:发表于2017-06-28 16:21 被阅读0次

总是有点似懂非懂的,本代码摘自http://www.tuicool.com/articles/mqUBFz

几个容易易卡住的点:

1.记忆化搜索写的时候要将相同交错和的个数,相同交错和的数字的和分别进行dp

2.对于一位数字和两位数字的计算方式并不相同,要分数字的位数进行讨论。

3.由于结果可能比较大,每一步都需要使用同余定理,以防运算过程中爆long long的情况。

记忆化搜索的思路,

当前的交错和相同的数字的和=sum(待搜索的状态的数字和+当前搜索的数字的大小*当前搜索到的符合条件的数字个数)。

#include <cstdio>
#include <cstring>
long long mod=1000000007;
long long base[20];
long long l,r,k,bit[20],bt,yy;
struct node {
    long long s,n;//s代表数字和,n代表数字个数
};
node dp[20][400];//状态转移
node dfs(long long pos,long long target,long long limit)//数位dp,基本可以算是模板啦
{
    node t;
    t.s=t.n=0;
    if (pos==0) {              //处理到最后一位,直接判断返回
        if (target==100)
        t.n=1;
        return t;
    }
    if ((limit==0)&&(dp[pos][target].n!=-1)) return dp[pos][target];
    long long tail=limit?bit[pos]:9;
    long long sgn=((yy-pos)%2)?(-1):(1);//确定符号
    long long head;
    if (pos==yy)head =1;
    else head=0;//确定搜索的起点和终点
    for (int i=head;i<=tail;i++)
    {
        node tmp=dfs(pos-1,target-i*sgn,(limit==1)&&(i==bit[pos]));
        if ((tmp.n)>0){
            t.n+=tmp.n;
            long long q;
            q=((((tmp.n%mod)*base[pos])%mod)*i)%mod;//结果的同余处理
            t.s+=(tmp.s)%mod;
            t.s%=mod;
            t.s+=q;
            t.s%=mod;//每一步都要同余
        }
    }
    if (limit==0) dp[pos][target]=t;
    return t;
}
long long cal(long long x,long long y)
{
    long long ans=0;
    if (x==-1) return 0;
    if (x==0) return 0;
    bt = 0;
    while (x)
    {
        bt++;
        bit[bt]=x%10;
        x/=10;
    }
    for (yy=1;yy<=bt;yy++){
        memset(dp,-1,sizeof dp);
        ans+=dfs(yy,y+100,yy==bt).s;//对于每个长度为yy的数字进行处理
        ans=(ans+mod)%mod;
    }
    return ans;
}
int main()
{
    base[1]=1;
    for (int i=2;i<=19;i++)
        base[i]=(base[i-1]*10)%mod;
    scanf("%lld%lld%lld",&l,&r,&k);
    {
        printf("%lld",(cal(r,k)-cal(l-1,k)+mod)%mod);
    }
    return 0;
}

相关文章

  • hihocoder1033(数位DP)

    总是有点似懂非懂的,本代码摘自http://www.tuicool.com/articles/mqUBFz 几个容...

  • 数位dp

    数位dp的入门题HDU - 2089 不要62题意:求区间[n,m]之间,不含有4和(连续的)62的数字个数。分析...

  • 数位dp

    数位dp是解决一类选择有约束的数字的个数的问题的解法,就是数一个区间有多少个满足题目条件的数字的个数,通常暴...

  • 数位DP

    1. 计数问题 原题链接[https://www.acwing.com/problem/content/340/]...

  • DP训练——数位DP

    数位DP BZOJ1026题意求到间,不含前导零且相邻两个数字之差至少为的正整数的个数。题解状态定义:表示当前处理...

  • 【进阶】数位DP详解

    今天,我向大家介绍一种特殊的DP类型——数位DP。数位DP这类题目一般不会出现在提高组及以下的比赛中(今后出现了当...

  • 数位dp入门

    之前稍微看过一点数位dp, 也没怎么练习, 现在鸽了这么久差不多全忘了. 今天一个小学弟跑来问我一个很水的题 多个...

  • [数位dp] Pair

    输入正整数A,B,C,统计满足1≤x≤A,1≤y≤B且至少满足下列条件之一:①x and y > C②x xor ...

  • 数位DP 详解

    序 天堂在左,战士向右 引言 数位DP在竞赛中的出现几率极低,但是如果不会数位DP,一旦考到就只能暴力骗分。以下是...

  • 动态规划-数位Dp

    记录今天在Acwing学习的几道数位Dp题目,整理了思路,方便以后的复习: 1.度的数量 题目描述 求给定区间 [...

网友评论

    本文标题:hihocoder1033(数位DP)

    本文链接:https://www.haomeiwen.com/subject/ozbucxtx.html