数位DP

news2024/9/23 15:21:49

数位dp的题目一般会问,某个区间内,满足某种性质的数的个数。

  1. 利用前缀和,比如求区间[l,r]中的个数,转化成求[0,r]的个数 [0,l-1]的个数。
  2. 利用树的结构来考虑(按位分类讨论)
    在这里插入图片描述

1081. 度的数量

#include<bits/stdc++.h>
using namespace std;
const int N=35;
int f[N][N],l,r,K,B;
//预处理组合数
int init()
{
    for(int i=0;i<N;i++)
        for(int j=0;j<=i;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>vec;
    while(n) vec.push_back(n%B),n/=B;//十进制转成B进制
    int res=0,last=0;
    //res记录答案数,last表示用了多少个1
    for(int i=vec.size()-1;i>=0;i--)
    {
        int x=vec[i];//取出第i位数
        if(x)//(如果当前位x==0直接进入右分支,讨论下一位)
        {
            res+=f[i][K-last];
            //当前位填0,从剩下的所有位(共有i位)中选K-last个数。
            //对应于:左分支中0的情况,合法
            if(x>1)
            {
                res+=f[i][K-last-1];
                break;
            }
            else//x==1,直接讨论下一位,可用的1的个数减1
            {
                last++;
                if(last>K) break;
            }
        }
        if(i==0&&last==K) res++;//遍历到最后一位且最后一位取1
    }
    return res;
}
int main()
{
    init();
    cin>>l>>r>>K>>B;
    cout<<dp(r)-dp(l-1)<<endl;
    return 0;
}

1082. 数字游戏

#include<bits/stdc++.h>
using namespace std;
const int N=15;
int f[N][N],l,r;
//f[i][j]表示一共有i位,且最高位为j的数的个数

int init()
{
    for(int j=0;j<=9;j++) f[1][j]=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>vec;
    while(n) vec.push_back(n%10),n/=10;
    int res=0,last=0;
    //res记录答案数,last表示上一位的数字
    for(int i=vec.size()-1;i>=0;i--)
    {
        int x=vec[i];//取出第i位数
        if(last>x) break;//这一位数无论怎么取都比上一位小
        for(int j=last;j<vec[i];j++)//进入左分支讨论
            res+=f[i+1][j];
        last=x;//更新lat
        if(!i) res++;//到了最后一位,剩下一种合法的情况
    }
    return res;
}
int main()
{
    init();
    while(cin>>l>>r)
        cout<<dp(r)-dp(l-1)<<endl;
    return 0;
}

1083. Windy数

#include<bits/stdc++.h>
using namespace std;
const int N=11;
int f[N][N],l,r;
//f[i][j]表示一共有i位,且最高位为j的数的个数
//存的是(包含前导零)的情况
int init()
{
    for(int j=0;j<=9;j++) f[1][j]=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>vec;
    while(n) vec.push_back(n%10),n/=10;
    int res=0,last=-2;
    //res记录答案数,last表示上一位的数字
    for(int i=vec.size()-1;i>=0;i--)
    {
        int x=vec[i];//取出第i位数
        for(int j=(i==vec.size()-1);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<vec.size();i++)
        for(int j=1;j<=9;j++)
            res+=f[i][j];//特判首位为零的情况
    return res;
}

int main()
{
    init();
    cin>>l>>r;
    cout<<dp(r)-dp(l-1)<<endl;
    return 0;
}

1084. 数字游戏 II

f[i][j][k] 表示一共有i位,且最高位数字是j,且所有位数字和%P结果为k的数的个数,若要转移到f[i][j][k]的状态,在i-1位对于每个x(x取值0~9)都应使第三维为(k-j)%P
状态转移方程:
f [ i ] [ j ] [ k ] = ∑ k = 0 P − 1 ∑ x = 0 9 f [ i − 1 ] [ x ] [ ( k − j ) % P ] f[i][j][k]=\sum_{k=0}^{P-1}\sum_{x=0}^{9}f[i-1][x][(k-j)\%P] f[i][j][k]=k=0P1x=09f[i1][x][(kj)%P]

用last表示到当前为止,前面数位上的数字之和,对此,当前第i位数字为j,前面数字之和为last,那么
后i位(包括j这一位)数字之和sum与last的关系就是
(last+sum)%N==0,那么sum%N==(-last)%N,
所以res+=f[i+1][j][(-last%N)];

#include<bits/stdc++.h>
using namespace std;
const int N=11;
int f[N][N][110],l,r,P;
//f[i][j][k]表示一共有i位,且最高位数字是j,且所有位数字和%P结果为k的数的个数
int mod(int u,int v)
{
    return (u%v+v)%v;
}
int 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<P;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>vec;
    while(n) vec.push_back(n%10),n/=10;
    int res=0,last=0;
    //res记录答案数,last表示前面所有位数上数字的和
    for(int i=vec.size()-1;i>=0;i--)
    {
        int x=vec[i];    
        for(int j=0;j<x;j++)  //第i位放0~x-1
            res+=f[i+1][j][mod(-last,P)]; //0~i位,所以一共有i+1位
        last+=x;
        if(!i&&last%P==0) res++;
        
    }
    return res;
}

int main()
{
    while(cin>>l>>r>>P)
    {
        init();
        cout<<dp(r)-dp(l-1)<<endl;
    }
    return 0;
}

1085. 不要62

#include<bits/stdc++.h>
using namespace std;
const int N=11;
int f[N][N],l,r;
//f[i][j]表示一共有i位,且最高位为j的数的个数

int init()
{
    for(int j=0;j<=9;j++) 
        if(j!=4) f[1][j]=1//一位不含5
    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>vec;
    while(n) vec.push_back(n%10),n/=10;
    int res=0,last=0;
    //res记录答案数,last表示上一位的数字
    for(int i=vec.size()-1;i>=0;i--)
    {
        int x=vec[i];//取出第i位数
        for(int j=0;j<x;j++) 
        {
            if(j==4||(j==2&&last==6)) continue;
            res+=f[i+1][j];
        }
        if(x==4||(x==2&&last==6)) break;
        last=x;
        if(!i) res++;
    }
    return res;
}

int main()
{
    init();
    while(cin>>l>>r,l||r)
        cout<<dp(r)-dp(l-1)<<endl;
    return 0;
}

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

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

相关文章

全网最全之接口测试【加密解密攻防完整版】实战教程详解

看视频讲的更详细&#xff1a;https://www.bilibili.com/video/BV1zr4y1E7V5/? 一、对称加密 对称加密算法是共享密钥加密算法&#xff0c;在加密解密过程中&#xff0c;使用的密钥只有一个。发送和接收双方事先都知道加密的密钥&#xff0c;均使用这个密钥对数据进行加密和解…

RedFish模拟仿真调试

前一段时间在真机上调试Redfish&#xff0c;自己一直想把模拟仿真给调试出来&#xff0c;想通过debug看看全部的流程细节&#xff0c;有空了也能自己玩玩&#xff0c;在github上RedfishPkg的页面有具体的说明&#xff0c;想看的移步&#xff1a; edk2-staging/RedfishPkg at e…

使用Vue实现数据可视化大屏功能(一)

导语   现在在很多的工程项目中&#xff0c;都有有关于数据大屏相关的监控内容&#xff0c;这里我们就来看一下如何用Vue来搭建一个数据可视化大屏应用。 创建项目 使用WebStorm工具创建一个Vue的项目。如下图所示&#xff0c;配置好vue的脚手架工具和nodejs的运行环境&#…

Httpclient测试

在IDEA中有一个非常方便的http接口测试工具httpclient&#xff0c;下边介绍它的使用方法&#xff0c;后边我们会用它进行接口测试。如果IDEA版本较低没有自带httpclient&#xff0c;需要安装httpclient插件1.插件2.controller进入controller类&#xff0c;找到http接口对应的方…

Unity - 搬砖日志 - BRP 管线下的自定义阴影尺寸(脱离ProjectSettings/Quality/ShadowResolution设置)

文章目录环境原因解决CSharp 脚本效果预览 - Light.shadowCustomResolution效果预览 - Using Quality Settings应用ControlLightShadowResolution.cs ComponentTools Batching add the Component to all LightReferences环境 Unity : 2020.3.37f1 Pipeline : BRP 原因 (好久没…

JVM系统优化实践(8):订单系统的垃圾回收案例

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e;上回说到了年轻代和老年代的两个垃圾回收器&#xff1a;ParNew和CMS&#xff0c;并且将CMS的GC过程也一并介绍了&#xff0c;现在来看个订单系统的案例。假设有这…

常见数据结构

一. 数据结构概述、栈、队列 1. 数据结构概述 2. 栈数据结构的执行特点 3. 常见数据结构之队列 二. 常见数据结构之数组 数组它就是内存中的一块儿连续区域。数组变量存的是数组在堆内存当中的起始地址。数组查询任意索引位置的值耗时相同&#xff0c;数组根据索引查询速度快。…

Matlab中旧版modem.qammod与新版不兼容

最近&#xff0c;因为课题需要&#xff0c;在研究通信。在网上下了一个2015年左右的代码&#xff0c;其中用的是matlab旧版中的modem.qammod函数&#xff0c;但是旧版中的函数已经被删除了&#xff0c;&#xff08;这里必须得吐槽一下&#xff0c;直接该函数内部运行机制就行呀…

Lasso回归理论及代码实现

Lasso回归的模型可以写作与一般线性回归相比, Lasso回归加入了回归项系数的一范数, 这样做是为了防止线性回归过程发生的过拟合现象. 直观点看, 其将的分量限制在了一个以圆点为中心以为边的正方形内. 与岭回归相比, 该模型得到的系数矩阵更为稀疏. 由于函数在0点不可导, 因而L…

第二章Linux操作语法1

文章目录vi和vim常用的三种模式vi和vim快捷键Linux开机&#xff0c;重启用户管理用户信息查询管理who和whoami用户组信息查询管理用户和组的相关文件实用指令集合运行级别帮助指令manhelp文件管理类pwd命令ls命令cd命令mkdir命令rmdir命令rm命令touch命令cp指令mv指令文件查看类…

Pytorch学习笔记#2: 搭建神经网络训练MNIST手写数字数据集

学习自https://pytorch.org/tutorials/beginner/basics/quickstart_tutorial.html 导入并预处理数据集 pytorch中数据导入和预处理主要用torch.utils.data.DataLoader 和 torch.utils.data.Dataset Dataset 存储样本及其相应的标签&#xff0c;DataLoader在数据上生成一个可迭…

刷题小抄4-数组

在Python中数组的功能由列表来实现,本文主要介绍一些力扣上关于数组的题目解法 寻找数组中重复的数字 题目链接 题目大意: 给出一个数组,数组长度为n,数组里的数字在[0,n-1]范围以内,数字可以重复,寻找出数组中任意一个重复的数字,返回结果 解法一 该题最基础的思路是使用字…

[java Spring JdbcTemplate配合mysql实现数据批量删除

之前的文章 java Spring JdbcTemplate配合mysql实现数据批量添加和文章java Spring JdbcTemplate配合mysql实现数据批量修改 先后讲解了 mysql数据库的批量添加和批量删除操作 会了这两个操作之后 批量删除就不要太简单 我们看到数据库 这里 我们用的是mysql工具 这里 我们有…

Java——单词接龙

题目链接 leetcode在线oj题——单词接龙 题目描述 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> … -> sk&#xff1a; 每一对相邻的单词只差一个字母。 对于 1 < i < k 时&#xff…

QML Text详解

1.简介 文本项可以显示普通文本和富文本。 2.示例 示例1&#xff1a;一个简单的text&#xff0c;可以设置字体颜色、大小等。 Window {visible: truewidth: 400height: 400title: qsTr("Hello World")Rectangle{width: 200height: 200border.width: 2Text {text: …

(flutter)黑苹果系统 Xcode iOS flutter 跑通真机模拟器 此oc clover 彼oc swift

前段时间写了关于flutter的一系列基础知识和入门的一些坑&#xff0c;中间把ios端的项目编译部署等工作一带而过&#xff0c;这里我觉得还是有必要专门写一篇文章来讲讲这个&#xff0c;顺便把环境问题也一起说了。 我们都知道开发ios应用需要用到苹果电脑&#xff0c;即使flu…

【NLP】Word2Vec 介绍

Word2Vec 是一种非常流行的自然语言处理技术&#xff0c;它将每个单词表示为高维向量&#xff0c;并且通过向量之间的相似度来表示单词之间的语义关系。 1 One-Hot 编码&#x1f342; 在自然语言处理任务中&#xff0c;我们需要将文本转换为计算机可以理解的形式&#xff0c;即…

ChatGPT后劲很大,问题也是

ChatGPT亮相即封神&#xff0c;最初的访客是程序员、工程师、AI从业者、投资人&#xff0c;最后是无数懵懂又好奇的普通人&#xff1a;ChatGPT是什么&#xff1f;自己会被ChatGPT取代吗&#xff1f;看待ChatGPT的立场也是两个极端&#xff1a; 快乐&#xff0c;是因为ChatGPT太…

科普| 什么是云原生?

“新冠疫情从根本上改变了商业模式&#xff0c;工作流向在线迁移的速度比以往任何时候都要快。越来越多的公司和消费者依靠电子商务“ B2B”和B2C”&#xff0c;以及网上银行促进创新以满足日益增长的客户需求&#xff0c;云原生技术在其中发挥重要作用&#xff0c;同时也加速了…

vm centos7搭建k8s集群

关闭防火墙&#xff0c;三台systemctl stop firewalld关闭selinux&#xff0c;三台sed -i s/enforcing/disabled/ /etc/selinux/config关闭swap&#xff0c;三台swapoff -a设置主机名&#xff0c;三台hostnamectl set-hostname 主机名&#xff0c;三个主机名分别设置成k8s-mast…