题402.数位dp-acwing-1082. 数字游戏1083. Windy数1085. 不要62

news2024/12/24 9:05:02

文章目录

  • 题402.数位dp-acwing-1082. 数字游戏
  • 一、题目
  • 二、题解
  • 三、类似题目
  • 四、关于数位dp


题402.数位dp-acwing-1082. 数字游戏


一、题目

在这里插入图片描述

二、题解

欲求区间[X,Y]中满足性质的数的个数,我们可以想着去求小于m的数中满足性质的个数f(m),然后利用前缀和思想,f(X,Y)=f(Y)-f(X-1)得到最后结果。
现在考虑如何求f(m):
对于上界m,设按B进制表示为an-1an-2an-3an-4…a1a0,则我们可以据此来给每一位填数,则以填最高位为例,新数该位要么填0-an-1-1(由于是要满足不降性质,因此最小只能填到上一位的数last),要么填an-1(当然也需满足不降性质),对于前者之后的位不论怎么填都可以满足比n来得小,则将满足性质的数的个数计入总的方案数,对于后者则last修改为当前位,然后须按照上述方式接着讨论,则整个过程可以按树讨论如下:

在这里插入图片描述

则我们还需开局预处理出给左分支使用的i位数时,最高位填j的结果f[i][j],对此可以使用dp来实现,以下直接对递推公式分析,采用y式dp分析法:

在这里插入图片描述
则代码如下:

#include <bits/stdc++.h>

using namespace std;

const int maxn=15;

int f[maxn][10];//f[i][j]表示i位数下最高位填j的方案数

void init()
{
    //初始化dp数组
    for(int i=0;i<=9;i++) f[1][i]=1;//1位数下最高位填i的方案数必定为1
    for(int i=2;i<maxn;i++)
    {
        for(int j=0;j<=9;j++)
        {
            for(int k=j;k<=9;k++)
            {
                f[i][j]+=f[i-1][k];//sum(1*f[i-1][k])
            }
        }
    }
}

int dp(int n)//求小于等于n的数中满足性质的数的个数
{
    if(!n) return 1;//上界为0时满足性质的数就是0,所以方案数为1

    //分离位数
    vector<int> nums;
    while(n) nums.push_back(n%10),n/=10;

    int res=0;
    int last=0;//last存储上一位填的数
    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];//左分支,res加上i+1位数下最高位填j([max(0,last),x-1])的方案数
        if(x<last) break;//右分支,填x,若x比last来的小则非法不填,直接break
        last=x;//
        if(!i) res++;//填到最后一位,方案数++
    }

    return res;
}

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

三、类似题目

1.acwing-1083. Windy数
(1)题目:
在这里插入图片描述
(2)代码:

#include <bits/stdc++.h>

#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=0;i--)
#define pb push_back

using namespace std;

const int maxn=11;

int f[maxn][10];

void init()
{
    rep(i,0,10) f[1][i]=1;
    rep(i,2,maxn)
    {
        rep(j,0,10)
        {
            rep(k,0,10)
            {
                if(abs(j-k)>=2) f[i][j]+=f[i-1][k];//注意是相差至少为2,不是当前位填的数一定要比上一位大2,所以是条件abs>=2
            }
        }
    }
}

int dp(int n)
{
    if(!n) return 0;
    vector<int> nums;
    while(n) nums.pb(n%10),n/=10;
    int res=0;
    int last=-2;
    per(i,0,nums.size())
    {
        int x=nums[i];
        rep(j,0,x)
        {
            if(!j&&i==nums.size()-1) continue;//刨去前导零的情况,这样最高位必为至少从1打头的数了
            if(abs(j-last)>=2) res+=f[i+1][j];
        }
        if(abs(x-last)<2) break;
        last=x;
        if(!i) res++;
    }
    rep(i,1,nums.size())//由于此前计入方案数时刨去前导零情况,所以这样要再做个特殊处理把因为前导0而成的(<n)位数方案计入
    {
        rep(j,1,10) res+=f[i][j];
    }
    return res;
}

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

2.acwing-1085. 不要62
(1)题目:
在这里插入图片描述

(2)代码:

#include <bits/stdc++.h>

using namespace std;

const int maxn=11;

int f[maxn][10];

void init()
{
    for(int i=0;i<=9;i++)
    {
        if(i!=4) f[1][i]=1;
    }
    for(int i=2;i<maxn;i++)
    {
        for(int j=0;j<=9;j++)
        {
            if(j==4) continue;
            for(int k=0;k<=9;k++)
            {
                if(k==4) continue;
                if(k==2&&j==6) 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=-1;
    for(int i=nums.size()-1;i>=0;i--)
    {
        int x=nums[i];
        for(int j=0;j<x;j++)
        {
            if(j==4) continue;
            if(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();
    int l,r;
    while(cin>>l>>r,l&&r)
    {
        cout<<dp(r)-dp(l-1)<<endl;
    }
}


四、关于数位dp

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


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

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

相关文章

WebDAV之葫芦儿·派盘+FX播放器

FX播放器 支持WebDAV方式连接葫芦儿派盘。 想要把手机、PC、NAS等设备上的视频在智能电视上大屏播放,支持超多格式的多合一视频播放器?快来试试FX播放器吧。 FX播放器除了存储在智能手机上的视频外,您网络上的视频也是实时无缝的࿰

关于TCP通信的学习和应用案例

记录学习TCP通信的过程&#xff0c;包括理论知识、在Qt中建立TCP服务端和客户端&#xff0c;并附上源代码。由于最近的项目中也使用到了海康VisionMaster软件&#xff0c;可以将其作为服务端&#xff0c;用Qt写的TCP客户端和其进行通信测试&#xff0c;方便调试。 目录1.关于TC…

MATLAB APP 设计实践(一)UART通信(上篇)

引言UART通信属于异步串行通信&#xff0c;通信速率比较低&#xff0c;在一些速度要求不高的场合常用来作为多设备之间的控制与被控制方式。例如以UART串口通信作为上位机侧与运行设备之间的通信形式&#xff0c;实现上位机对设备的操控以及检测设备运行状态等。那么谈到了上位…

PyTorch实战1

传送门&#xff1a;蓝桥云课实验 目录1. 实验环境2. 实验目的3. 相关原理4. 实验步骤4.1 数据预处理4.1.1 对于类型变量的处理4.1.2 对于数值类型变量进行标准化4.1.3 数据集分割4.2 创建模型手写用Tensor运算的人工神经网络4.3 训练模型4.3.1 数据的分批次处理4.4 测试模型1. …

逆向-还原代码之eth (Arm 64)

// 源程序 #include <stdio.h> #define HIETH_SYSREG_BASE (0x101e0000) #define REG_RESET 0x01C // 外设控制寄存器(IP软复位控制) #define RESET_SHIFT 12 static void hieth_set_regbit(unsigned long addr, int bit, int shift) { unsigned long …

Practise test day16

一.单选 1.在关系型是数据库中&#xff0c;有两个不同的事务同时操作数据库中同一表的同一行&#xff0c;不会引起冲突的是&#xff1a;&#xff08;F&#xff09; A. 其中一个DELETE操作&#xff0c;一个是SELECT操作 B. 其中两个都是UPDATE C. 其中一个是SELECT&#xff…

ruoyi通过oauth对接pig实现sso流程讲解

1、时序图 2、流程解析 本流程是以使用Ruoyi对接Pig授权中心为例&#xff0c;进行讲解&#xff0c;其他网站的的oauth的原理都和这个一样&#xff0c;所以只要把这个流程搞懂了即可&#xff0c;接下来就按照真实的流程进行逐步解析。 2.1 第1步 用户还未登录&#xff0c;访问r…

浏览器Performance性能监控使用详解

文章目录1.Performance2.测试性能操作流程3.Performance检测结果详解区域1&#xff1a;controls【控制栏】区域2&#xff1a;overview【网页性能总览图】区域3&#xff1a;火焰图【各项指标的堆叠追踪可视化】区域4&#xff1a;统计汇总【以图表的形式汇总数据】4 其他监控性能…

BGP在数据中心的应用6——BGP在服务器上的应用

注&#xff1a; 本文根据《BGP in the Datacenter》整理&#xff0c;有兴趣和英文阅读能力的朋友可以直接看原文&#xff1a;https://www.oreilly.com/library/view/bgp-in-the/9781491983416/上一部分笔记请参考&#xff1a;https://blog.csdn.net/tushanpeipei/article/deta…

视频如何在线生成二维码?视频转二维码的2种方法

现在很多小伙伴都喜欢将视频转二维码&#xff0c;通过这种方式来分享传递内容&#xff0c;那么如何将视频生成二维码更加的简单快捷呢&#xff1f;大家可以用一下小编分享的这款在线二维码生成工具来制作二维码&#xff0c;通过浏览器在线生成二维码&#xff0c;更加的简单快捷…

设计模式——迭代器模式

迭代器模式一、基本思想二、结构图三、代码一、基本思想 提供一个对象来顺序访问聚合对象中的一系列数据&#xff0c;而不暴露聚合对象的内部表示。迭代器模式是一种对象行为型模式&#xff0c;其主要优点如下&#xff1a; 访问一个聚合对象的内容而无须暴露它的内部表示。遍…

【Kotlin】函数 ④ ( 匿名函数参数 | 匿名函数 it 关键字 )

文章目录一、匿名函数参数二、匿名函数 it 关键字一、匿名函数参数 匿名函数 可以不带参数 , 也可以带多个参数 ; 不带参数的匿名函数 : // 声明 函数类型 变量, 并为其赋值 匿名函数val helloFun: ()->String {"Hello World"}带参数的匿名函数 : 匿名函数 的 参…

安装一个Excel插件,轻松网罗50+主流数据库

电子表格软件&#xff08;Smartbi Spreadsheet&#xff09;是思迈特软件推出的企业报表产品&#xff0c;产品以“真Excel”为特色&#xff0c;只需要安装一个小小插件&#xff0c;就能解决Excel最头疼的数据连接和性能问题。电子表格软件的数据源范围涵盖了本地数据库、关系型数…

如何学习虚幻引擎的Blueprint?

&#xff08;虚幻学习路线-方法概括版&#xff09; 【写在前面】&#xff1a;本篇内容颇多&#xff0c;并不是一大堆全学&#xff0c;把这篇当成一个字典&#xff0c;选择性学习&#xff0c;缺哪学哪~ 一、Blueprint &#xff08;一&#xff09;什么是虚幻引擎的Blueprint&…

C++STL之list容器

一&#xff1a;list特性list为带哨兵位双向循环链表&#xff0c;支持任意位置的插入和删除。与&#xff08;array&#xff0c;vector&#xff0c;deque&#xff09;相比&#xff0c;list的移除元素效率更高。最大缺陷是不支持[]重载&#xff0c;不支持随机访问&#xff0c;只能…

基于 EventBridge API Destination 构建 SaaS 集成实践方案

作者&#xff1a;赵海 引言 事件总线 EventBridge 是阿里云提供的一款无服务器事件总线服务&#xff0c;支持阿里云服务、自定义应用、SaaS 应用以标准化、中心化的方式接入&#xff0c;并能够以标准化的 CloudEvents 1.0 协议在这些应用之间路由事件&#xff0c;帮助您轻松构…

Mockjs入门基础概念与使用

文章目录Mockjs入门使用1、概述2、安装引入3、语法规范3.1 数据模板定义规范&#xff08;DTD)3.1.1 DTD介绍3.1.2 规范实例演示字符串String数字Number布尔Boolean对象Object数组Array函数Function正则表达式RegExp3.2 数据占位符定义规范DPD4、关于Mock.mock()方法4.1 参数介绍…

RabbitMQ 常见面试题

RabbitMQ 常见面试题 1.为什么要用消息队列? (消息队列的应用场景?) 2.各种消息队列产品的比较? 3.消息队列的优点和缺点? 4.如何保证消息队列的高可用? 5.如何保证消息不丢失? 6.如何保证消息不被重复消费?(如何保证消息消费的幂等性&#xff09; 7.如何保证消息消费的…

PMP证书好考吗?

PMP 还是很好考的&#xff0c;各大机构 3A 的人也很多&#xff0c;我的备考经验分享给大家参考下&#xff0c;大家可以取长补短&#xff0c;找到适合自己的备考方法&#xff1a;一、复习计划的制定根据之前在培训班共同奋斗的小伙伴学习时间统计&#xff0c;平均每天的学习时间…

我的第一门编程语言

元旦节在家重温了一遍《三体》&#xff0c;看到下面一段描写&#xff1a;监听部的计算机系统也远比发射部庞大复杂&#xff0c;叶文洁第一次走进主机房时&#xff0c;看到一排阴极射线管显示屏&#xff0c;她惊奇地发现&#xff0c;屏幕上竟滚动着一排排程序代码&#xff0c;可…