看到这题用循环写的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. 大型图像数据聚类匹配:ICCV2019论文解析

    大型图像数据聚类匹配:ICCV2019论文解析 Jointly Aligning Millions of Images with Deep Penalised Reconstruction Conge ...

  2. Single Shot Multibox Detection (SSD)实战(下)

    Single Shot Multibox Detection (SSD)实战(下) 2. Training 将逐步解释如何训练SSD模型进行目标检测. 2.1. Data Reading and In ...

  3. Activiti Exploer工作流控制台使用指南!使用Activiti Explorer定义部署执行工作流

    Activiti Explorer简介 Activiti Explorer: Activiti控制台,是一个web应用程序 从Activiti的官方网站下载Activiti的压缩zip文件时,Acti ...

  4. 使用cookies,免密登录禅道(一)

    导言:在做自动化的过程中,很多时候都需要绕过登录验证码来进行测试,可使用cookie 绕过验证码进行登录. 以下以自己搭建的禅道环境登录为例(其他网站也可以同样道理): #coding=gbkimpo ...

  5. fiddler选项卡-Statistc(统计)

    Statistc Statistc是fiddler用来对session列表里的Session相关情况的统计,利用这个选项,可以对请求进行性能以及其他数据分析 1.界面 2.参数详解 建议:打开fidd ...

  6. [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & Driver

    [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & Driver 目录 [源码解析] 深度学习分布式训练框架 horovod (4) --- 网络基础 & ...

  7. 华为云数据库GaussDB(for Cassandra)揭秘第二期:内存异常增长的排查经历

    摘要:华为云数据库GaussDB(for Cassandra) 是一款基于计算存储分离架构,兼容Cassandra生态的云原生NoSQL数据库:它依靠共享存储池实现了强一致,保证数据的安全可靠. 本文 ...

  8. 痛并快乐的YOLO初体验

    1.前言 最近因为需要研究视频的物体识别和行为识别,上网了解了一下,YOLO是目前实时视频物体识别的应用最广泛的算法. 因此,作为小白的我,也准备体验一下YOLO算法的效果. 先上网了解了一下YOLO ...

  9. 混沌工程之ChaosToolkit使用之一删除K8s POD

    今天我们来玩一下混沌工程的开源工具chaostoolkit . 它的目标是提供一个免费,开放,社区驱动的工具集以及api. 官方源码链接:https://github.com/chaostoolkit ...

  10. 记一次ios下h5页面图片显示问题

    刚入职公司时做了一个移动端图片预览的组件,之前也有业务组用过,没发现什么问题,但是这次有两个很诡异的问题. 一个是老数据的图不显示,另一个是图片点击预览只显示一部分加载不全.之所以诡异是所有设备都没问 ...