算法竞赛备赛进阶之数位DP训练

数位DP的思想就是对每一位进行DP,计算时记忆化每一位可以有的状态,其作用是减少运算时间,避免重复计算。

数位DP是一种计数用的DP,一般就是要统计一个区间[A,B]内满足一些条件数的个数。

以1e9甚至1e18、1e100的问题为例,因为在统计情况下有很多重复的计算,数位DP实现了相同状态只计算一次,从而大幅减少运算时间。

数位DP:

技巧1:[X, Y] => f(Y) - f(X-1)

技巧2:用树进行排列

1.度的数量

1081

求给定区间[X, Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和。

例如。设X=15,Y=20,K=2,B=2,择优且仅有下列三个数满足题意:

17 = 24 + 20

18 = 24 + 21

20 = 24 + 22

输入格式

第一行包含两个整数X和Y,接下来两行包含整数K和B

#include<iostream>
#include<algorithm>
#include<vector>
​
using namespace std;
​
const int N = 35;
​
int K, B;
int f[N][N];
​
void init()
{for(int i = 0;i < N; i++)for(int j = 0;j <= N; j++)if(!j) f[i][j] = 1;else f[i][j] = f[i - 1][j] + f[i - 1][j - 1];
}
​
int dp(int n)
{if(!n) return 0;vector<int> nums;while(n){nums.push_back(n % B);n /= B;}int res = 0;int last = 0;for(int i = nums.size() - 1;i >= 0; i--){int x = nums[i];if(x)//求左边的分支{res += f[i][K - last];if(x > 1){if(K - last - 1 >= 0) res += f[i][K - last - 1];break;}else {last++;if(last > K) break;}}if(!i && last == K) res++; // 最右侧分支上的方案}return res;
}
​
int main()
{init();int l, r;cin >> l >> r >> K >> B;cout << dp(r) - dp(r - 1) << endl;return 0;
}

2.数字游戏

科协里最近很流行数字游戏。

某人命名了一种不降数,这种数字必须满足从左到右各位数字呈现非下降关系,如123,446

现在大家决定玩一个游戏,指定一个整数闭区间[a, b],问这个区间内有多少个不降数。

动态规划

  1. 状态表示

    1. 集合:所有最高位是j,且一共有i位的不降数的集合

    2. 属性:数量

  2. 状态计算

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
​
using namespace std;
​
const int N = 40;
​
int f[N][N]; // f[i][j]表示一共有i位,且最高位填j的数的个数
​
void init()
{for(int i = 0;i <= 9; i++) f[1][i] = 1;for(int i = 2;i < N; i++)for(int j = 0;j <= 9; j++)for(int k = j;k <= 9; k++)f[i][j] += f[i - 1][k];
}
​
int dp(int n)
{if(!n) return 1;vector<int> nums;while(n){nums.push_back(n % 10);n /= 10;}int res = 0;int last = 0;for(int i = nums.size() - 1;i >= 0; i--){int x = nums[i];for(int j = last;j < x; j++)res += f[i + 1][j];if(last > x)break;last = x;if(!i) res++;}return res;
}
​
int main()
{void init();int l, r;while(scanf("%d%d", &l, &r)){cout << dp[r] - dp[l - 1] << endl;}return 0;
}

3.Windy数

1083.Windy定义了一种Windy数:不包含前导零且相邻两个数字之差至少为2的正整数被称为Windy数。

Windy想知道,在A和B之间,包括A和B,总共有多少个Windy数?

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
​
using namespace std;
​
const int N = 11;
​
int f[N][10];
​
void init()
{for(int i = 0;i <= 9; i++) f[1][i] = 1;for(int i = 2;i < N; i++)for(int j = 0;j <= 9; j++)for(int k = 0;k <= 9; k++)if(abs(j - k) >= 2)f[i][j] += f[i - 1][k];
}
​
int dp(int n)
{if(!n) return 0;vector<int> nums;while(n) nums.push_back(n % 10), n /= 10;int res = 0;int last = -2;for(int i = nums.size() - 1;i >= 0; i--){int x = nums[i];for(int j = 0;j < x; j++)if(abs(j - last) >= 2)res += f[i + 1][j];if(abs(x - last) >= 2) last = x;else break;if(!i) res++;}// 特殊枚举有前导零for(int i = 1;i < nums.size(); i++)for(int j = 1;j <= 9;+)res += f[i][j];return res;
}
​
int main()
{init();int l, r;cin >> l >> r;cout << dp(r) - dp(l - 1) << endl;return 0;
}

4.数字游戏II

1084.由于科协里最近真的很流行数字游戏。

某人又命名了一种取模数,这种数字必须满足各位数字之和mod N 为0

现在大家又要玩游戏了,指定一个整数闭区间[a, b],问这个区间内有多少个取模数。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
​
using namespace std;
​
const int N = 11, M = 110;
​
int P;
int f[N][10][M];
​
int mod(int x, int y)
{return (x % y + y) % y;
}
​
void init()
{memset(f, 0, sizeof(f));for(int i = 0;i <= 9; i++) f[1][i][i % P]++;for(int i = 2;i < N; i++)for(int j = 0;j <= 9; j++)for(int k = 0;k < N; k++)for(int x = 0;x <= 9; x++)f[i][j][k] += f[i - 1][x][mod(k - j, P)];
}
​
int dp(int n)
{if(!n) return 1;vector<int> nums;while(n) nums.push_back(n % 10), n /= 10;int res = 0;int last = 0;for(int i = nums.size() - 1;i >= 0; i--){int x = nums[i];for(int j = 0;j < x; j++)res += f[i + 1][j][mod(-last, P)];last += x;if(!i && last % P == 0) res++;}return res;
}
​
int main()
{int l, r;while(cin >> l >> r >> P){init();cout << dp[r] - dp[l - 1] << endl;}return 0;
}

5.不要62

1085.杭州人称那些傻乎乎黏兮兮的人为62。

杭州交通管理局经常会扩充一些的士车牌照。附近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士机和乘客的心理障碍,更安全地服务大众。

不吉利的数字为所有含有4或62的号码。如:62315,73418,88914都属于不吉利号码。但是,61152虽然含有6和2,但不是逐号,所以不属于不吉利数字之列。

你的任务是,对于每次给出的一个牌照号区号[n, m],推断出交管局今后又要实际上给多少辆的士车上牌照了。

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
​
using namespace std;
​
const int N = 9;
​
int f[N][10];
​
void init()
{for(int i = 0;i <= 9; i++)if(i != 4)f[1][i] = 1;for(int i = 2;i < N; i++)for(int j = 0;j <= 9; j++){if(j == 4) continue;for(int k = 0;k <= 9; k++){if(k == 4 || j == 6 && k == 2)continue;f[i][j] += f[i - 1][k];}}
}
​
int dp(int n)
{if(!n) return 1;vector<int> nums;while(n) nums.push_back(n % 10), n /= 10;int res = 0;int last = 0;for(int i = nums.size() - 1;i >= 0; i--){int x = nums[i];for(int j = 0;j < x; j++){if(j == 4 || last == 6 && j == 2) continue;res += f[i + 1][j];}if(x == 4 || last == 6 && x == 2) break;last = x;if(!i) res++;}return res;
}
​
int main()
{init();int l, r;while(cin >> l >> r, l || r){cout << dp[r] - dp[l - 1] << endl;}return 0;
}

6.恨7不成妻

1086.DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌!

吉哥观察了214和77这两个数,发现:   2+1+4=7   7+7=72   77=711 最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数!

什么样的数和7有关呢?

如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关—— 1、整数中某一位是7; 2、整数的每一位加起来的和是7的整数倍; 3、这个整数是7的整数倍;

现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
​
using namespace std;
​
typedef long long LL;
​
const int N = 20, P = 1e9 + 7;
​
struct F
{int s0, s1, s2;
}f[N][10][7][7];
​
int power7[N], power9[N];
​
int mod(LL x, int y)
{return (x % y + y) % y;
}
​
void init()
{for(int i = 0;i <= 9; i++){if(i == 7) continue;auto &v = f[1][i][i % 7][i % 7];v.s0++;v.s1 += i;v.s2 += i * i;}LL power = 10;for(int i = 2;i < N; i++, power *= 10)for(int j = 0;j < N; j++){if(j == 7) continue;for(int a = 0;a < 7; a++)for(int b = 0;b < 7; b++)for(int k = 0;k <= 9; k++){if(k == 7) continue;auto &v1 = f[i][j][a][b], &v2 = f[i - 1][k][mod(a - j * (power % 7), 7)][mod(b - j, 7)];v1.s0 = (v1.s0 + v2.s0) % P;v1.s1 = (v1.s1 + j * (power % P) * v2.s0 + v2.s1) % P; v1.s2 = (v1.s2 + j * j * (power % P) % P * (power % P) % P * v2.s0) % P + 2 * j * (power % P) % P * v2.s1 % P + v2.s2) % P;}}power7[0] = power9[0] = 1;for(int i = 1;i < N; i++){power7[i] = power7[i - 1] * 10 % 7;power9[i] = power9[i - 1] * 10 % P;}
}
​
F get(int i, int j, int a, int b)
{int s0 = 0, s1 = 0, s2 = 0;for(int x = 0;x < 7; x++)for(int y = 0;y < 7; y++){if(x == a || y == b) continue;auto v = f[i][j][x][y];s0 = (s0 + v.s0) % P;s1 = (s1 + v.s1) % P;s2 = (s2 + v.s2) % P;}return {s0, s1, s2};
}
​
int dp(LL n)
{if(!n) return 0;LL backup_n = n % P;vector<int> nums;while(n) nums.push_back(n % 10), n /= 10;int res = 0;LL last_a = 0, last_b = 0;for(int i = nums.size() - 1;i >= 0; i--){int x = nums[i];for(int j = 0;j < x; j++){if(j == 7) continue;int a = mod(-last_a % 7 * power7[i + 1], 7);int b = mod(-last_b, 7);auto v = get(i + 1, j, a, b);res = (res + (last_a % P) * (last_a * P) % P * power9[i + 1] % P * power9[i + 1] % P * v.s0 % P + 2 (last_a % P) % P * power9[i + 1] % P * v.s1 % P + v.s2) % P;}if( x == 7) break;last_a = last_a * 10 + x;last_b += x;if(!i && last_a % 7 && last_b % 7) res += (res + backup_n * backup_n) % P;}return res;
}
​
int main()
{init();int T;cin >> T;while(T--){int l, r;cin >> l >> r;cout << mod(dp(r) - dp(l - 1), P) << endl;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/626676.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLOv8改进 | 主干篇 | EfficientViT高效的特征提取网络完爆MobileNet系列(轻量化网络结构)

一、本文介绍 本文给大家带来的改进机制是主干网络,一个名字EfficientViT的特征提取网络(和之前发布的只是同名但不是同一个),其基本原理是提升视觉变换器在高效处理高分辨率视觉任务的能力。它采用了创新的建筑模块设计,包括三明治布局和级联群组注意力模块。其是一种高效率…

【ELK 学习】ElasticSearch

ELK&#xff1a;ElasticSearch存储&#xff0c;Logstash收集&#xff0c;Kibana展示 版本较多&#xff0c;使用时需要版本匹配&#xff0c;还需要和mysql版本匹配&#xff08;elastic官网给了版本对应关系&#xff09; 本次使用的版本es6.8.12 filebeat 轻量级的数据收集工具 …

多视图多标签学习

一、多视图学习 多视图学习又称多视角学习&#xff0c;在实际应用问题中&#xff0c;对于同一事物可以从多种不同的途径或不同的角度进行描述&#xff0c;这些不同的描述构成了事物的多个视图。例如&#xff1a;在与人们生活息息相关的互联网中&#xff0c;网页数据既可以用网…

C++ 设计模式之享元模式

【声明】本题目来源于卡码网&#xff08;题目页面 (kamacoder.com)&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【简介】什么是享元模式 -- 可重复使用 享元模式是⼀种结构型设计模式&#xff0c;在享元模式中&#xff0c;对象被…

我记不住的那些位操作bitwise(一)

背景&#xff1a; 最近在看底层的一些知识内容&#xff0c;其中有一些位操作&#xff0c;所以想复习并记录一下。 一、或 或&#xff1a; 0 | 1 1 及 1 | 1 1 但是无法区分这两种情况(1. 一个是false&#xff0c;另一个是true&#xff1b; 2. 这两个都是true) 在C语…

PDF控件Spire.PDF for .NET【安全】演示:更改 PDF 文档的安全权限

当您使用密码保护 PDF 文档时&#xff0c;您可以选择指定一组权限。权限决定用户如何与文件交互。例如&#xff0c;您可以对文档应用权限以禁止用户打印或使用剪切和粘贴操作。本文演示如何在C# 和 VB.NET中使用Spire.PDF for .NET更改 PDF 文档的安全权限。 Spire.PDF for .N…

HTML5 article标签,<time>...</time>标签和pubdate属性的运用

1、<article>...</article>标签的运用 article标签代表文档、页面或应用程序中独立的、完整的、可以独自被外部引用的内容。它可以是一篇博客或报竟杂志中的文章、一篇论坛帖子、一段用户评论或一个独立的插件&#xff0c;或者其他任何独立的内容。把文章正文放在h…

新喜报,新希望!英码科技荣登“2023年广州拟上市领头羊TOP50企业榜单”

近日&#xff0c;广州市资本市场融资对接服务平台启动仪式暨2023年拟上市企业“领头羊”评选总结活动成功举办。活动现场发布了2023年广州“拟上市领头羊TOP 50 企业榜单”、“最受资本关注TOP10榜单”、“最强科创TOP10榜单”、“最具成长TOP10榜单”并为企业颁发牌匾&#xf…

HCIA 网络基础:

应用层 抽象语言-->编码 表示层 编码-->二进制 会话层 建立会话&#xff0c;提供绘画地址。 应用于程序内部进行区分&#xff0c;没有统一标准 上三层主要是软件层面&#xff08;应用 程序处理数据&#xff09; 下四层主要负责数据传输 传输层 端口号 分段 &#xff…

Ubuntu开机自动挂载硬盘

前言&#xff1a; 因为我的电脑是WIN10 Ubuntu18.04双系统&#xff0c;且两个系统都装在C盘上&#xff0c;而D盘作为数据和代码存储盘&#xff0c;经常会开机就被访问&#xff0c;例如上一次关机前用VS Code访问D盘代码&#xff0c;然后下一次开机的时候打开VSCode发现打不开…

在window宿主机访问WSL2内部署的服务

目录 在window宿主机访问 WSL2 内部署的服务&#xff08;其他&#xff09;在 WSL2 内查看 windows&#xff08;宿主机&#xff09;的IP地址 windows内置了Linux系统&#xff08;WSL&#xff09;。 在window宿主机访问 WSL2 内部署的服务 在WSL下部署的项目&#xff0c;比如端口…

智能分析网关V4基于AI视频智能分析技术的周界安全防范方案

一、背景分析 随着科技的不断进步&#xff0c;AI视频智能检测技术已经成为周界安全防范的一种重要手段。A智能分析网关V4基于深度学习和计算机视觉技术&#xff0c;可以通过多种AI周界防范算法&#xff0c;实时、精准地监测人员入侵行为&#xff0c;及时发现异常情况并发出警报…

text expressing

文章目录 前言文本表示1文本特征概念介绍2 文本特征选择方法3 文本表示方法 text expressing3.1 One Hot(独热)编码3.2 TF-IDF 模型3.3 Word2Vec 参考链接&#xff1a; 前言 文本是一种非结构化的数据信息&#xff0c;是不可以直接被计算的。 文本表示的作用就是将这些非结构…

powershell的help

打开win10 的powershell窗口&#xff0c;输入help命令&#xff0c;可以得到如下说明&#xff1a; 有了help系统&#xff0c;可以方便地了解关于powershell的详细说明。

文献阅读(速读):Automating Deep Neural Network Model Selection for Edge Inference

目录 论文简介动机&#xff1a;为什么作者想要解决这个问题&#xff1f;贡献&#xff1a;作者在这篇论文中完成了什么工作(创新点)&#xff1f;规划&#xff1a;他们如何完成工作&#xff1f;自己的看法(作者如何得到的创新思路) 论文简介 作者 Bingqian Lu、Jianyi Yang、Lydi…

cesium设置近地天空盒 天空会倾斜

上篇文章讲解了如何设置近地天空盒&#xff0c;效果出来了还是发现天空是斜的 https://blog.csdn.net/m0_63701303/article/details/135618244 效果&#xff1a; 这里需要修改Cesium.skyBox的代码&#xff0c;代码如下直接全部复制组件内调用即可 skybox_nearground.js&…

分布式光伏运维平台在提高光伏电站发电效率解决方案

摘要&#xff1a;伴随着能源危机和环境恶化问题的日益加重&#xff0c;科技工作者进一步加大对新能源的开发和利用。太阳能光伏发电作为新型清洁能源的主力军&#xff0c;在实际生产生活中得到了广泛的应用。然而&#xff0c;光伏发电效率偏低&#xff0c;成为制约光伏发电发展…

机器学习算法实战案例:LSTM实现单变量滚动风电预测

文章目录 1 数据处理1.1 数据集简介1.2 数据集处理 2 模型训练与预测2.1 模型训练2.2 模型滚动预测2.3 结果可视化 答疑&技术交流机器学习算法实战案例系列 1 数据处理 1.1 数据集简介 实验数据集采用数据集5&#xff1a;风电机组运行数据集&#xff0c;包括风速、风向、…

webpack打包可视化分析工具:webpack-bundle-analyzer

在对webpack项目进行优化的时候,可以使用webpack-bundle-analyzer这个可视化插件来快速分析我们包的结构,能快速定位需要优化的地方,对开发者非常友好 下载安装 下载依赖包 npm i webpack-bundle-analyzer 使用 const BundleAnalyzerPlugin require(webpack-bundle-analy…

qt.qpa.plugin: Could not find the Qt platform plugin “windows“ in ““

系统环境&#xff1a;Win10家庭中文版 Qt : 5.12.9 链接了一些64位的第三方库&#xff0c;程序编译完运行后出现 qt.qpa.plugin: Could not find the Qt platform plugin "windows" in "" 弹窗如下&#xff1a; 网上搜了一些都是关于pyQt的&#xff0c…