看到这题用循环写的dp代码瑟瑟发抖~

数位dp一般记忆化搜索的写法思维难度较低,也比较常用,这题的简洁代码应该就可以显现出其优越性

(用时4ms,可能比用循环写的dp还要快)

那这里补充一下记忆化搜索的写法叭qwq保姆式超详细讲解哦

有注释代码

#include<iostream>
#include<cstring>
using namespace std; typedef long long ll;
const ll P=1e9+7;
int A[25];
ll pw[25]; struct node {ll cnt,sum,sum2;} f[20][7][7]; /*
f[I][sum][num]表示的状态为:
从第I位开始,最高位到第I位每位数字之和(%P)为sum,整个数字(%P)为num
如对于数123***,I=3时,sum=6,num=123 注:f存储的是在没有贴合上界的情况下
因为没有贴合上界,即剩下i位可以从00…00~99…99随便填,所以无论数a[]是多少都可以适用,不需要每次都重置f数组 在该状态下,结构体中的
cnt表示与7无关的数的个数
sum表示所有与7无关的数的和
num表示所有与7无关的数的平方和
*/ node dfs(int I,int sum,int num,bool lim){ //当前在第I位,最高位到第I位每位数字之和(%P)为sum,整个数字(%P)为num,lim表示是否贴合上界
if (!I) return (node){sum && num , 0 , 0}; //数字已填完,根据题目要求,若sum和num都不为0(不能被7整除),则算一种方案
if (!lim && f[I][sum][num].cnt>=0) return f[I][sum][num]; //记忆化,如果不贴合上界(!lim),直接放回记录过的答案 int up=lim ? A[I] : 9; //第I位最大能填的数
node ans=(node){0,0,0};
for (int i=0 ; i<=up ; i++) //枚举第I位填的数
if (i!=7){
node J=dfs(I-1,(sum+i)%7,(num*10+i)%7,lim && i==up);
ll B=i*pw[I-1]; //B可以理解为当前层的基值,例如第I=5位填6,则B=60000
(ans.cnt+=J.cnt)%=P; //统计与7无关数出现次数
(ans.sum+=J.cnt*B+J.sum)%=P; /*
统计所有与7无关数的和(用dfs(I-1)已经求出了所有无关数第I-1位到最后一位所组成的数之和,即J.sum,再加上第I位即可,即J.cnt*B)
例如I=5,已知无关数有**61111,**62222,**63333(随便瞎写的几个数字)
则B=60000,J.sum=1111+2222+3333,J.cnt=3,ans.sum=61111+62222+63333
*/ (ans.sum2+=J.cnt*B%P*B%P+J.sum2+2*J.sum%P*B%P)%=P; /*
统计所有与7无关数第I位到最后一位所组成的数的平方和
例如I=5,已知无关数有**61111,**62222,**63333(随便瞎写的几个数字)
对于61111^2=(60000+1111)^2=(60000)^2+(1111)^2+2*60000*1111
62222,63333同理
则ans.sum2=61111^2+62222^2+63333^2
=3*(60000)^2 + (1111^2+2222^2+3333^2) + 2*60000*(1111+2222+3333)
=J.cnt*B*B + J.sum2 + 2*B*J.sum
可以发现,我们用后I-1位的sum2即可推算出后I位的sum2
*/
}
if (!lim) f[I][sum][num]=ans; //记忆化:如果不贴合上界(!lim),则记录
return ans;
} ll solve (ll X){ //分解数位
int len=0;
for ( ; X ; X/=10) A[++len]=X%10;
return dfs(len,0,0,1).sum2;
} int main(){
int T;
cin>>T,pw[0]=1,memset(f,-1,sizeof f);
for(int i=1 ; i<21 ; i++) pw[i]=pw[i-1]*10%P; //预处理10的幂 for (ll L,R ; T ; T--)
scanf("%lld%lld",&L,&R),printf("%lld\n",(solve(R)-solve(L-1)+P)%P);
}

无注解代码

#include<iostream>
#include<cstring>
using namespace std; typedef long long ll;
const ll P=1e9+7;
int A[25];
ll pw[25]; struct node {ll cnt,sum,sum2;} f[20][7][7]; node dfs(int I,int sum,int num,bool lim){
if (!I) return (node){sum && num , 0 , 0};
if (!lim && f[I][sum][num].cnt>=0) return f[I][sum][num]; int up=lim ? A[I] : 9;
node ans=(node){0,0,0};
for (int i=0 ; i<=up ; i++)
if (i!=7){
node J=dfs(I-1,(sum+i)%7,(num*10+i)%7,lim && i==up);
ll B=i*pw[I-1];
(ans.cnt+=J.cnt)%=P;
(ans.sum+=J.cnt*B+J.sum)%=P;
(ans.sum2+=J.cnt*B%P*B%P+J.sum2+2*J.sum%P*B%P)%=P;
}
if (!lim) f[I][sum][num]=ans;
return ans;
} ll solve (ll X){
int len=0;
for ( ; X ; X/=10) A[++len]=X%10;
return dfs(len,0,0,1).sum2;
} int main(){
int T;
cin>>T,pw[0]=1,memset(f,-1,sizeof f);
for(int i=1 ; i<21 ; i++) pw[i]=pw[i-1]*10%P; for (ll L,R ; T ; T--)
scanf("%lld%lld",&L,&R),printf("%lld\n",(solve(R)-solve(L-1)+P)%P);
}

有问题的话欢迎在评论区留言哦~

AcWing 1086. 恨7不成妻(【代码简洁】标准记忆化搜索+超详解!!)的更多相关文章

  1. Appium+python自动化(三十)- 实现代码与数据分离 - 数据配置-yaml(超详解)

    简介 本篇文章主要介绍了python中yaml配置文件模块的使用让其完成数据和代码的分离,宏哥觉得挺不错的,于是就义无反顾地分享给大家,也给大家做个参考.一起跟随宏哥过来看看吧. 思考问题 前面我们配 ...

  2. java代码之美(13)--- Predicate详解

    java代码之美(13)--- Predicate详解 遇到Predicate是自己在自定义Mybatis拦截器的时候,在拦截器中我们是通过反射机制获取对象的所有属性,再查看这些属性上是否有我们自定义 ...

  3. 菜刀(代码执行)函数和命令执行函数详解及Getshell方法

    i春秋作家:大家奥斯的哦 原文来自:https://bbs.ichunqiu.com/thread-41471-1-1.html 代码执行函数 VS 命令执行函数 一直想整理这两块的内容,但是一直没时 ...

  4. Appium+python自动化(三十二)- 代码写死一时爽,框架重构火葬场 - PageObject+unittest(超详解)

    简介 江湖有言:”代码写死一时爽,框架重构火葬场“,更有人戏言:”代码动态一时爽,一直动态一直爽

  5. Appium+python自动化(三十九)-Appium自动化测试框架综合实践 - 代码实现(超详解)

    简介 经过一段时间的准备,完善的差不多了,继续分享有关Appium自动化测试框架综合实践.想必小伙伴们有点等不及了吧! driver配置封装 kyb_caps.yaml 配置表 参考代码 platfo ...

  6. Appium+python自动化(四十)-Appium自动化测试框架综合实践 - 代码实现(超详解)

    1.简介 今天我们紧接着上一篇继续分享Appium自动化测试框架综合实践 - 代码实现.由于时间的关系,宏哥这里用代码给小伙伴演示两个模块:注册和登录. 2.业务模块封装 因为现在各种APP的层出不群 ...

  7. 【随笔】菜刀(代码执行)函数和命令执行函数详解及Getshell方法

    代码执行函数 VS 命令执行函数 一直想整理这两块的内容,但是一直没时间弄,直到前两天碰上一个写入了菜刀马但是死活连不上菜刀的站,顿时不知道怎么继续了,所以就趁这个机会整理了一下代码执行函数怎么get ...

  8. 【hdu4057】 恨7不成妻

    http://acm.hdu.edu.cn/showproblem.php?pid=4507 (题目链接) 题意 求区间${[a,b]}$中的某些数的平方和,这些数要满足1.不是7的倍数,2.不含有7 ...

  9. hdu4507吉哥系列故事——恨7不成妻 (数位dp)

    Problem Description 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: ...

随机推荐

  1. js中reduce用法详解

    介绍reduce reduce() 方法接收一个函数作为累加器,reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(上一次回调的返回值),当 ...

  2. 图像实例分割:CenterMask

    图像实例分割:CenterMask CenterMask: single shot instance segmentation with point representation 论文链家: http ...

  3. halcon——缺陷检测常用方法总结(频域空间域结合)

    摘要 缺陷检测是视觉需求中难度最大一类需求,主要是其稳定性和精度的保证.首先常见缺陷:凹凸.污点瑕疵.划痕.裂缝.探伤等. 缺陷检测算法不同于尺寸.二维码.OCR等算法.后者应用场景比较单一,基本都是 ...

  4. HashMap底层实现原理及面试常见问题

    HashMap底层源码分析 1.HashMap底层采用的存储结构 1.在JDK1.7及之前采用的存储结构是数组+链表 2.到了JDK1.8之后采用的是数组+链表+红黑树 2.HashMap实现的原理 ...

  5. P5132 Cozy Glow之拯救小马国

    题目描述 Cozy Glow偷偷摸摸的造了一个魔法阵,这个魔法阵在吸取小马国的魔力,所以你得赶紧把它毁掉. 这个魔法阵由若干个神器组成,每个神器都有一个法力值,每两个神器之间也都有一个关联值.你要依次 ...

  6. SVN报错“Failed to run the WC DB work queue associated with”解决办法

    最近在更新SVN上的ISO代码时,失败报错:  Failed to run the WC DB work queue associated with "目录/文件",clean u ...

  7. C#关于数据库中存储的用户权限类似 "普通员工,管理员" 如何在代码中读取分析权限

    之前在看某些数据库的用户权限的表时,发现字段是这样类似这样存储的"  普通员工,管理员 ",当时觉得他们是通过分割字符串来分析权限的.后来读到 Liam Wang  的 https ...

  8. 简述MSTP与配置

    一.简介 二.MSTP概述 三.功能 四.配置命令 一.简介 多生成树协议MSTP(Multiple Spanning Tree Protocol)是IEEE 802.1s中定义的生成树协议,通过生成 ...

  9. 六、JavaSE语言基础之数组

    一维数组(关键字[]) 关于数组的一些概念: 数组是多个基本数据有机组合形成一个复杂数据,是一个引用数据类型数据. 数组:装指定数量元素类型相同的数据的容器. 元素:在数组中,数组中的每个数据称之为数 ...

  10. 生产环境部署Django项目

    生产环境部署Django项目 1.  部署架构 IP地址 安装服务 172.16.1.251 nginx uwsgi(sock方式) docker mysql5.7 redis5 Nginx 前端We ...