#1033 : 交错和

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描写叙述

给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数:

f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1

比如:

f(3214567) = 3 - 2 + 1 - 4 + 5 - 6 + 7 = 4

给定

输入

输入数据仅一行包括三个整数。l, r, k(0 ≤ l ≤ r ≤ 1018, |k| ≤ 100)。

输出

输出一行一个整数表示结果,考虑到答案可能非常大,输出结果模 109 + 7。

提示

对于例子 ,满足条件的数有 110 和 121,所以结果是 231 = 110 + 121。

很多其它例子:

Input
4344 3214567 3
Output
611668829
Input
404491953 1587197241 1
Output
323937411
Input
60296763086567224 193422344885593844 10
Output
608746132
Input
100 121 -1
Output
120
例子输入
100 121 0
例子输出
231

中文题=_=题目出处来自hihocoder第一次挑战赛,xiaodao出题。

刚開始做的时候脑洞开大了以为是数论专题,后来才发现是数位dp,几个easy易卡住的点:

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;
}

[hihocoder 1033]交错和 数位dp/记忆化搜索的更多相关文章

  1. 数位dp/记忆化搜索

    一.引例 #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an  ...

  2. 【poj1850】 Code 数位dp+记忆化搜索

    题目大意:给你一个字符串,问你这个字符串的rank,如果这个字符串不合法,请直接输出0.(一个合法的字符串是对于∀i,有c[i]<c[i+1]) 字符串s的rank的计算方式:以字符串长度作为第 ...

  3. [BZOJ3598][SCOI2014]方伯伯的商场之旅(数位DP,记忆化搜索)

    3598: [Scoi2014]方伯伯的商场之旅 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 449  Solved: 254[Submit][Sta ...

  4. bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)

    1833: [ZJOI2010]count 数字计数 题目:传送门 题解: 今天是躲不开各种恶心DP了??? %爆靖大佬啊!!! 据说是数位DP裸题...emmm学吧学吧 感觉记忆化搜索特别强: 定义 ...

  5. 1026-windy数+数位DP+记忆化搜索

    1026: [SCOI2009]windy数 题意:数位DP模板题: 目前只理解了记忆化搜索,就想练练手, ------给递推写法留一个位子 ------ 注意这道题要判断前导0的情况,1 )可以加一 ...

  6. 【每日dp】 Gym - 101889E Enigma 数位dp 记忆化搜索

    题意:给你一个长度为1000的串以及一个数n 让你将串中的‘?’填上数字 使得该串是n的倍数而且最小(没有前导零) 题解:dp,令dp[len][mod]为是否出现过 填到第len位,余数为mod 的 ...

  7. luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索

    题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...

  8. hihoCoder 1033 : 交错和 数位dp

    思路:数位dp,dp(i, j, k)表示考虑i位数,每位数可以任意取[0~9],并且这i位数的交错和为j,k=1表示前缀全是0(如000456),k=0表示前缀不为0.注意,前缀是否为0是这道题的一 ...

  9. hdu3652 数位dp记忆化搜索

    从未见过的船新版本数位dp,,省去了预处理过程,直接进行计算 #include<bits/stdc++.h> using namespace std; #define ll long lo ...

随机推荐

  1. android源代码百度网盘分享

    转载请标明出处:  http://blog.csdn.net/yujun411522/article/details/46334123 本文出自:[yujun411522的博客] 近期在使用Ubunt ...

  2. vim的基本使用方法

    头记:vim作为被大多数程序员所推崇的编辑器,是源于它的自由灵活以及令人舒服的输入模式,但对于新手来说无疑是个噩梦(需要记太多的命令), 而作为使用了vim有一段时间的我来说,总结下常用的命令,以备新 ...

  3. C#。5 结构体

    结构体:相当于是我们自己定义的一种复杂的类型. 常见简单类型:int...  double float bool char string 常见复杂类型:DateTime  数组类型 生活中大部份的对象 ...

  4. js操作符

    JS操作符 x + y(数字) 将x和y相加; x + y(字符串) 将x和y拼接在一起; x - y 从x中减去y; x * y 将x和y相乘; x / y 将x除以y; x % y x和y的模(既 ...

  5. 打印HTML页面部分区域javascript代码

    function preview(oper) { if (oper < 10) { bdhtml = window.document.body.innerHTML; //获取当前页的html代码 ...

  6. Swift中可能失败的构造器的传播(调用)和重写

    import Foundation /* 可能失败构造器的传播(调用) 1.可能失败的构造器可以调用同一个类中的普通构造器 2.普通构造器不能调用同一个类中的可能失败构造器 3.结构体中, 普通构造器 ...

  7. static在类中的定义,和enum的用法

    class A { // static int a = 1;//错误,静态变量在类外定义 static int a; static const int b = 1;//如果是静态成员常量,则可以在类内 ...

  8. hdu2896

    数据水,但是各种wa各种t各种re最后照着别人的改了改发现了毛病 数组做指针传入的时候系统是不知道传入后的数字的长度的如果用memset他就只会讲指针的地方清零 #include<iostrea ...

  9. mysql索引之唯一索引

    mysql 的唯一索引一般用于不重复的字段,一般会把表中的id设为唯一索引,创建唯一索引的目的不是为了提高查询速度,而是为了避免数据重复,注意:唯一索引可以有多个,但是列值必须唯一,创建唯一索引使用关 ...

  10. spark1.3.1使用基础教程

    spark可以通过交互式命令行及编程两种方式来进行调用: 前者支持scala与python 后者支持scala.python与java 本文参考https://spark.apache.org/doc ...