C++知识点总结(58):序列型动态规划

news2024/11/25 9:18:58

动态规划Ⅰ

  • 一、基础
    • 1. 意义
    • 2. 序列 dp 解法
  • 二、例题
    • 1. 最大子段和
    • 2. 删数最大子段和(数据强度:pro max)
    • 3. 最长上升子序列(数据强度:pro max)
    • 4. 3 或 5 的倍数序列
    • 5. 数码约数序列

一、基础

1. 意义

动态规划(dynamic programming,简称 dp,将一个目标大问题“大事化小,小事化了”,分成很多的子问题,得出子问题的解后得到目标大问题的解。动态规划相当于地狱难度的递推。

问题P
子问题P1
子问题P1的解
问题P的解
子问题P2
子问题P2的解
子问题P3
子问题P3的解
子问题P4
子问题P4的解

2. 序列 dp 解法

序列型动态规划分为几种常见的问题:

  • 取连续的子段(串)
    • dp[i] 表示以 i i i 为结尾
  • 取子序列(不要求连续)
    • dp[i] 表示以 i i i 为结尾
    • dp[i] 表示 0 ∼ i 0\sim i 0i 中 …
    • dp[i] 长度为 i i i 序列结尾的性质
  • 分段
    • dp[i] 表示以 i i i 为结尾

二、例题

1. 最大子段和

题目描述

给出数组 a a a,如果我们取连续且非空的一段,那么这段的和最大是多少?

输入描述

1 1 1 行,是一个正整数 n n n,数组 a a a 的长度。
2 2 2 行,用空格隔开的 n n n 个整数,依次是 a [ 1 ] ∼ a [ n ] a[1]\sim a[n] a[1]a[n] 的值。

输出描述

1 1 1 个整数,为所求的最大的和

样例1

输入

6
1 -6 5 -4 2 4

输出

7

提示

【样例解释】
5 , − 4 , 2 , 4 5,−4,2,4 5,4,2,4 可以得到最大的和 7 7 7
【数据范围】
对于 60 % 60\% 60% 的数据, n ≤ 100 n≤100 n100
对于 80 % 80\% 80% 的数据, n ≤ 5000 n≤5000 n5000
对于 100 % 100\% 100% 的数据, n ≤ 100000 n≤100000 n100000

【问题类型】 取子段
【问题解法】 dp[i] 表示以 a[i] 为结尾的最大子段和是多少
【模板技巧】 如果前面都是负数,我不跟它们同流合污(a[i]);如果前面大的,那就加入它们,做一个更大的数(dp[i-1]+a[i]
【参考答案】

#include<bits/stdc++.h>
using namespace std;
int n,maxn=-1e8;
int a[100005];
int dp[100005];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    dp[1]=a[1];
    for(int i=2;i<=n;i++){
        dp[i]=max(a[i],dp[i-1]+a[i]);
        maxn=max(maxn,dp[i]);
    }
    cout<<maxn;
    return 0;
}

2. 删数最大子段和(数据强度:pro max)

给出一个数组 a[],删除一个元素后,求它的最大子段和。(子段是指数组中连续的一段元素)删除的元素可以由你自由选择,但是不能不删除任何元素,输出你能得到的最大的子段和。

思路:要删掉 a[i] 的时候会产生两个切口,第一个是以 a[i-1] 为结尾,第二个是以 a[i+1] 为开头。以 a[i-1] 为结尾取一个非常大的子段,以 a[i+1] 为开头取一个非常大的子段,将它们组合在一起,就可以完成本题。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN=1e6+8;
const int NEGINF=-1e18;
int n,ans=NEGINF;
int a[MAXN],dpl[MAXN],dpr[MAXN];
/*
* dpl[i]:以i为右端点的最大子段和
* dpr[i]:以i为左端点的最大子段和
*/
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)
        dpl[i]=max(dpl[i-1]+a[i],a[i]);
    for(int i=n;i>=1;i--)
        dpr[i]=max(dpr[i+1]+a[i],a[i]);
    for(int i=1;i<=n;i++)
        ans=max({ans,dpl[i-1],dpr[i+1],dpl[i-1]+dpr[i+1]});//选择左边/右边/左边和右边
    cout<<ans;
    return 0;
}

3. 最长上升子序列(数据强度:pro max)

求出数组 a[] 的最长上升子序列⻓度。

参考答案:

#include<bits/stdc++.h>
using namespace std;
int n,sz;
int a[5005];
int dp[5005];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++){
        if(sz==0||a[i]>dp[sz])sz++,dp[sz]=a[i];
        else{
            int p=lower_bound(dp+1,dp+sz+1,a[i])-dp;
            dp[p]=a[i];
        }
    }
    cout<<sz;
    return 0;
}

4. 3 或 5 的倍数序列

给出一个序列 a[],要求你从中找出一个子序列,满足子序列中任意相邻两数之和是 3 3 3 5 5 5 的倍数。

#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e3+8;
const int MOD=1e9+7;
int n,a[MAXN],dp[MAXN];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<i;j++)
            if((a[i]+a[j])%3==0||(a[i]+a[j])%5==0)
                dp[i]=(dp[i]+dp[j]+1)%MOD;
        ans=(ans+dp[i])%MOD;
    }
    cout<<ans;
    return 0;
}

5. 数码约数序列

给出一个序列 a[],要求你从中找出一个子序列,满足子序列中任意相邻两数,前一个数的末位数码是后一个数的首位数码的约数。
例如 302 , 817 , 739000 302,817,739000 302,817,739000 是一个满足要求的序列,因为 302 302 302 的末位 2 2 2 807 807 807 的首位 8 8 8 的约数; 817 817 817 的末位 7 7 7 739000 739000 739000 的首位 7 7 7 的约数。 但是 70 , 1 70,1 70,1 就不满足要求,因为 0 0 0 不是 1 1 1 的约数。
问所有满足要求的子序列中,总和最大的序列的和是多少?(单独一个数也算满足要求的序列)

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+8;
long long n,dp[MAXN][10];
int main(){
    cin>>n;
    for(int i=1,a,fst,lst;i<=n;i++){
        cin>>a,fst=a,lst=a%10;
        while(fst>=10)fst/=10;
        for(int j=0;j<=9;j++)
            dp[i][j]=dp[i-1][j];
        for(int j=1;j<=fst;j++)
            if(fst%j==0)
                dp[i][lst]=max(dp[i][lst],dp[i-1][j]+a);
    }
    long long ans=0;
    for(int i=0;i<=9;i++)ans=max(ans,dp[n][i]);
    cout<<ans;
    return 0;
}

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

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

相关文章

如何安全删除 Linux 用户帐户和主目录 ?

Linux 以其健壮性和灵活性而闻名&#xff0c;是全球服务器和桌面的首选。管理用户帐户是系统管理的一个基本方面&#xff0c;包括创建、修改和删除用户帐户及其相关数据。本指南全面概述了如何在 Linux 中安全地删除用户帐户及其主目录&#xff0c;以确保系统的安全性和完整性。…

如何利用ros搭建虚拟场景通过仿真机器人完成一次简单的SLAM建图、导航规划(超简单)?——学习来源:机器人工匠阿杰

一&#xff1a;什么是SLAM&#xff0c;SLAM和导航规划又有什么关系&#xff1f; SLAM&#xff08;Simultaneous Localization and Mapping&#xff0c;即同时定位与建图&#xff09;是一种在未知或动态环境中自行驶的重要技术。主要通过设备上的传感器&#xff08;如激光雷达、…

shell脚本(完结)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址&#xff1a;shell编程&#xff08;完结&#xff09;_哔哩哔哩_bilibili 本文主要讲解不同shell脚本中的相互调用以及输入输出重定向操作。 一、不同脚本之间…

禁用达梦DEM的agent

agent占用内存较多&#xff0c;实际没什么使用&#xff0c;考虑停止agent 应该切换到root执行停止 cd /dm/dmdbms/tool/dmagent/service/ ./DmAgentService stop禁用

使用ChatGPT生成和优化电子商务用户需求规格说明书

在电子商务项目开发中&#xff0c;用户需求规格说明书&#xff08;User Requirement Specification, URS&#xff09;是团队沟通与项目成功的基石。然而&#xff0c;面对复杂多变的需求&#xff0c;如何快速生成清晰、完整且具备说服力的文档&#xff1f;这正是AI工具的用武之地…

产品研发管理和研发项目管理的区别是什么

产品研发管理与研发项目管理有显著的区别&#xff0c;主要体现在管理范围、目标导向和执行方法上。产品研发管理侧重于产品生命周期的规划与执行&#xff0c;强调产品的创新性和市场需求对接&#xff0c;而研发项目管理则更注重具体项目的执行过程&#xff0c;聚焦项目时间、成…

摆烂仙君传——深度学习秘境奇缘

第一章&#xff1a;深度学习秘境 在修仙界与科技交织的边缘&#xff0c;八荒六合九天无上摆烂仙君在其高科技修炼室中感应到一股神秘的召唤。这股力量似乎与他的灵魂产生了共鸣&#xff0c;引导他前往传说中的深度学习秘境。在那里&#xff0c;古老的仙法与前沿的算法交织&…

【FPGA开发】Vivado自定义封装IP核,绑定总线

支持单个文件的封装、整个工程的封装&#xff0c;这里用单个文件举例。 在文件工程目录下&#xff0c;自建一个文件夹&#xff0c;里面放上需要封装的verilog文件。 选择第三个&#xff0c;指定路径封装&#xff0c;找到文件所在目录 取个名&#xff0c;选择封装IP的路径 会…

【CS61A 2024秋】Python入门课,全过程记录P2(Week3开始,更新中2024/11/24)

文章目录 关于基本介绍&#x1f44b;Week 3Mon Environments阅读材料Lab 02: Higher-Order Functions, Lambda ExpressionsQ1: WWPD: The Truth Will PrevailQ2: WWPD: Higher-Order FunctionsQ3: WWPD: Lambda 关于 个人博客&#xff0c;里面偶尔更新&#xff0c;最近比较忙。…

在Linux下配置gitee与Github的远程仓库

目录 前言 云服务器下载git 检测是否下载成功git Linux下配置gitee远程仓库 代码提交演示 git三板斧 Linux下配置Github远程仓库 最后的提醒 前言 那么本篇文章将是在&#xff0c;你已经创建了本地仓库的基础上&#xff0c;在Linux下配置gitee的远程仓库的步骤&#xff…

Mac配置maven环境及在IDEA中配置Maven

Mac配置maven环境及在IDEA中配置Maven 1. 介绍 Maven是一款广泛用于Java等JVM语言项目的工具&#xff0c;它以项目对象模型&#xff08;POM&#xff09;为基础进行项目管理&#xff0c;通过POM文件来定义项目信息和依赖关系。同时&#xff0c;它也是构建自动化工具&#xff0…

硬中断关闭后的堆栈抓取方法

一、背景 性能和稳定性是一个计算机工程里的一个永恒的主题。其中尤其稳定性这块的问题发现和问题分析及问题解决就依赖合适的对系统的观测的手段&#xff0c;帮助我们发现问题&#xff0c;识别问题原因最后才能解决问题。稳定性问题里尤其底层问题里&#xff0c;除了panic问题…

STL关联式容器之hashtable

hashtable的桶子与节点 下图为开链法(separate chaining)完成hashtable的图形表述。为了剖析SGI STL源码&#xff0c;我们遵循SGI的命名&#xff0c;称hash table表格内的元素为桶(bucket),此名称的大约意义是&#xff0c;表格内的每个单元&#xff0c;涵盖的不只是个节点(元素…

基于python的长津湖评论数据分析与可视化,使用是svm情感分析建模

引言 研究背景及意义 上世纪初开始&#xff0c;中国电影就以自己独有的姿态登上了世界电影史的舞台。中国电影作为国家文化和思想观念的反映与延伸&#xff0c;能够增强文化自信&#xff0c;在文化输出方面有着极其重要的作用1[1]。 改革开放以来&#xff0c;随着生产力的提高…

阿里云oss转发上线-实现不出网钓鱼

本地实现阿里云oss转发上线&#xff0c;全部代码在文末&#xff0c;代码存在冗余 实战环境 被钓鱼机器不出网只可访问内部网络包含集团oss 实战思路 若将我们的shellcode文件上传到集团oss上仍无法上线&#xff0c;那么就利用oss做中转使用本地转发进行上线&#xff0c;先发送…

预测未来 | MATLAB实现Transformer时间序列预测未来

预测未来 | MATLAB实现Transformer时间序列预测未来 预测效果 基本介绍 1.Matlab实现Transformer时间序列预测未来&#xff1b; 2.运行环境Matlab2023b及以上&#xff0c;data为数据集&#xff0c;单变量时间序列预测&#xff1b; 3.递归预测未来数据&#xff0c;可以控制预…

局域网与广域网:探索网络的规模与奥秘(3/10)

一、局域网的特点 局域网覆盖有限的地理范围&#xff0c;通常在几公里以内&#xff0c;具有实现资源共享、服务共享、维护简单、组网开销低等特点&#xff0c;主要传输介质为双绞线&#xff0c;并使用少量的光纤。 局域网一般是方圆几千米以内的区域网络&#xff0c;其特点丰富…

可视化建模与UML《协作图实验报告》

有些鸟儿毕竟是关不住的。 一、实验目的&#xff1a; 1、熟悉协作图的构件事物。 2、掌握协作图的绘制方法。 二、实验环境&#xff1a; window7 | 10 | 11 EA15 三、实验内容&#xff1a; 下面列出了打印文件时的工作流&#xff1a; 用户通过计算机指定要打印的文件。(2)打…

docker搭建私有的仓库

docker搭建私有仓库 一、为什么要搭建私有的仓库&#xff1f; 因为在国内&#xff0c;访问&#xff1a;https://hub.docker.com/ 会出现无法访问页面。。。。&#xff08;已经使用了魔法&#xff09; 当然现在也有一些国内的镜像管理网站&#xff0c;比如网易云镜像服务、Dao…

微信小程序条件渲染与列表渲染的全面教程

微信小程序条件渲染与列表渲染的全面教程 引言 在微信小程序的开发中,条件渲染和列表渲染是构建动态用户界面的重要技术。通过条件渲染,我们可以根据不同的状态展示不同的内容,而列表渲染则使得我们能够高效地展示一组数据。本文将详细讲解这两种渲染方式的用法,结合实例…