DP的优化途径---单调队列

news2024/9/8 23:23:33

1.前缀和+单调队列:https://www.acwing.com/problem/content/137/

我们先预处理下前缀和,以下标为i的点为有边界:

ans=max(ans,sum[i]-sum[j])(i-m\leqslant j\leqslant i-1)

也就是求sum[j](i-m\leqslant j\leqslant i-1)的min,考虑到j的范围是定值,用单调队列维护即可。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node{
    int t;
    ll zhi;
};
int n,m;
ll a[300006];
ll sum[300006];
node q[300006];
int tail=-1,head=0;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    ll ans=-1e18;
    for(int i=0;i<=n;i++){
        if(tail>=head&&(q[head].t<=i-m-1)) head++;
        if(tail>=head) ans=max(ans,sum[i]-q[head].zhi);
        while(tail>=head&&q[tail].zhi>=sum[i]) tail--;
        q[++tail]={i,sum[i]};
    }
    cout<<ans;
    
}

2.DP+单调队列:https://www.acwing.com/problem/content/1089/

先维护出来前缀和,令dp[i]表示前i个的最大效率,答案就是dp[n]

我们考虑状态转移:

dp[i]=max(dp[i-1],max(sum[i]-sum[j]+dp[j-1])(i-k\leqslant j\leqslant i-1))

于是我们把dp值放入单调队列即可。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll n,k;
ll a[100010],sum[100010],dp[100010];
ll q[100010],head=0,tail=-1;
int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];
    dp[0]=a[0];
    q[++tail]=0;
    for(int i=1;i<=n;i++){
        while(tail>=head&&i-k>q[head]) head++;
        dp[i]=max(sum[i]+dp[q[head]-1]-sum[q[head]],dp[i-1]);
        ll xx=dp[i-1]-sum[i];
        while(tail>=head&&xx>dp[q[tail]-1]-sum[q[tail]]) tail--;
        q[++tail]=i;
    }

   
    cout<<dp[n];

}

3.DP+单调队列:https://www.acwing.com/problem/content/1091/

令dp[i]表示前i个第i个一定选的最小花费:

dp[i]=a[i]+min(dp[j]),用单调队列维护。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[200010],dp[200010];
int q[200010],tail=-1,head=0;
int ans=0x7f7f7f7f;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>a[i];
    q[++tail]=1;
    dp[1]=a[1];
    for(int i=2;i<=n;i++){
        while(tail>=head&&q[head]<i-m) head++;
        if(i<=m) dp[i]=a[i];
        else dp[i]=a[i]+dp[q[head]];
        while(tail>=head&&dp[i]<dp[q[tail]]) tail--;
        q[++tail]=i;
    }
    //for(int i=1;i<=n;i++) cout<<dp[i]<<" ";
    for(int i=n-m+1;i<=n;i++) ans=min(ans,dp[i]);
    cout<<ans;
}

4.二维的单调队列:https://www.acwing.com/problem/content/1093/

想到要维护出来每一个正方形的max与min,我们可以考虑先对行进行单调队列,求出行方向连续k个的最值,然后再对列进行一遍,这样就求出每一个正方行的最值了。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m, k, res = 1e9;
int w[N][N], minv[N][N], maxv[N][N], que[N];
int a[N], b[N], c[N], d[N];
void get_max(int a[], int f[], int m)
{
    int hh = 0, tt = -1;
    for (int i = 1; i <= m; i ++ )
    {
        while (hh <= tt && i - que[hh] >= k) hh ++ ;
        while (hh <= tt && a[i] >= a[que[tt]]) tt -- ;
        que[ ++ tt] = i;
        f[i] = a[que[hh]];
    }
}
void get_min(int a[], int f[], int m)
{
    int hh = 0, tt = -1;
    for (int i = 1; i <= m; i ++ )
    {
        while (hh <= tt && i - que[hh] >= k) hh ++ ;
        while (hh <= tt && a[i] <= a[que[tt]]) tt -- ;
        que[ ++ tt] = i;
        f[i] = a[que[hh]];
    }
}
int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            scanf("%d", &w[i][j]);
    for (int i = 1; i <= n; i ++ )
    {
        get_min(w[i], minv[i], m);
        get_max(w[i], maxv[i], m);
    }

    for (int i = k; i <= m; i ++ )
    {
        for (int j = 1; j <= n; j ++ )
        {
            a[j] = maxv[j][i];
            b[j] = minv[j][i];
        }
        get_max(a, c, n);
        get_min(b, d, n);
        for (int j = k; j <= n; j ++ ) res = min(res, c[j] - d[j]);
    }
    printf("%d\n", res);
}

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

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

相关文章

家具缓冲器:提升家居体验的得力助手

在家具和工业设备的设计与制造中&#xff0c;钢珠滑轨缓冲器的安装与否一直是一个备受争议的话题。钢珠滑轨缓冲器作为一种能够减少冲击和噪音的装置&#xff0c;其存在具的价值&#xff0c;但也并非在所有情况下是必需的。首先&#xff0c;从功能和使用体验的角度来看&#xf…

【C++题解】1581. 马里奥的银币1

问题&#xff1a;1581. 马里奥的银币1 类型&#xff1a;数组找数 题目描述&#xff1a; 马里奥有很多银币&#xff0c;有一天他得到了一张魔法卡&#xff0c;只要使用这张魔法卡&#xff0c;就可以使得他的银币里面的最大的银币金额变得更大。如果他最大的银币是偶数的金额&a…

【Vue3】watchEffect

【Vue3】watchEffect 背景简介开发环境开发步骤及源码 背景 随着年龄的增长&#xff0c;很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来&#xff0c;技术出身的人总是很难放下一些执念&#xff0c;遂将这些知识整理成文&#xff0c;以纪念曾经努力学习奋斗的日子。本文…

001.精读《Big Data: A Survey》

文章目录 1. 引言2. 精读2.1 摘要2.2 背景2.4 相关技术2.5 相关流程2.6 应用场景 3. 总结 1. 引言 大数据精读周刊首次与大家正式见面。我们每周将精读并分析几篇精选文章&#xff0c;试图讨论并得出结论性观点。我们的目标是通过深入探讨&#xff0c;帮助大家更好地理解大数据…

力扣高频SQL 50题(基础版)第二十五题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第二十五题619.只出现一次的最大数字题目说明实现过程准备数据实现方式结果截图 力扣高频SQL 50题&#xff08;基础版&#xff09;第二十五题 619.只出现一次的最大数字 题目说明 MyNumbers 表&#xff1a; ------…

Qt,获取其他.exe文件的标准输出流的信息(printf/print的输出信息)

比如&#xff0c;通过Python编写爬虫软件功能是运行程序获取豆瓣电影排行榜信息&#xff0c;并通过print打印出来。将其打包成.exe,通过Qt来调用&#xff0c;并获取到.exe程序运行的结果 简单示例代码&#xff1a; // 创建 QProcess 对象QProcess process;// 连接信号槽以获取…

java计算器,输入公式和对应变量的值

目标&#xff1a;最近想写个东西&#xff0c;本质就是一个计算器&#xff0c;我们可以输入公式&#xff08;例如&#xff1a;ab&#xff09;&#xff0c;然后把公式的值&#xff08;a:10,b:20&#xff09;也输入进去。最后得到结果。核心&#xff1a;这个想法核心部分就是给一个…

Git远程仓库推送

这里我只连接了两个站点的远程仓库&#xff0c;一个是国内的Gitee&#xff0c;另一个是Github&#xff0c;这两个站点的连接方式主要有两种&#xff0c;第一种就是通过https来连接远程仓库&#xff0c;另一种是通过ssh公钥来连接&#xff0c;这两个站点练接的大致过程都是一样的…

接口测试支持IDEA插件一键同步API、新增思维导图快速评审测试用例,MeterSphere开源持续测试工具v3.1.0版本发布

2024年7月29日&#xff0c;MeterSphere开源持续测试工具正式发布v3.1.0版本。 在这一版本中&#xff0c;接口测试方面&#xff0c;支持通过IDEA插件一键同步API至MeterSphere&#xff1b;测试管理方面&#xff0c;“测试用例”模块新增通过思维导图模式快捷评审测试用例。在“…

【SpringCloud】Nacos配置管理和Feign远程调用

Nacos配置管理和Feign远程调用 Nacos一方面可以将配置集中管理&#xff0c;另一方可以在配置变更时&#xff0c;及时通知微服务&#xff0c;实现配置的热更新。 一、Nacos配置管理 1. 统一配置管理 1.1.在Nacos中添加配置文件 注&#xff1a;项目的核心配置&#xff0c;需…

如何在Net8.0平台下开发AOT项目,项目实战分析

1. 前言 前面的文章我们讨论过什么是AOT&#xff0c;以及AOT适用于什么场景&#xff0c; dotnet开发编译之争&#xff1a;Ahead-of-Time(AOT) vs Just-in-Time(JIT)谁才是未来最佳编译选择&#xff1f;&#xff0c;那么如何在Net8.0平台下开发AOT项目。 2. 先决条件 在安装的…

【JavaEE】通过Linux部署Web项目到云服务器上

一.配置部署所需的环境. 1.1 什么是部署? 要想知道什么是部署, 就要先了解我们在日常开发的过程中所设计到的几种环境: 开发环境: 软件开发环境指的是开发人员在创建、测试和部署软件应用程序时所需的一系列硬件、软件、工具和流程的集合。它是为了支持软件开发过程而构建的…

各路数据库的第一

各路第一 上周很多朋友都在发这些。朋友圈被刷屏了。 而且几乎都是同一时间。一般来说文无第一武无第二&#xff0c;怎么全是第一&#xff1f; 后来了解到这是不同维度的。我想这大概和奥斯卡颁奖一样&#xff0c;最佳导演、最佳男主角、最佳女主角、最佳音乐等等有20多个维度…

FPGA开发——LED流水灯实现先从左往右流水,再从右往左流水

一、概述 我们在设计完一个方向的流水灯的设计时&#xff0c;总是会想实现让流水灯倒着流水回去的设计&#xff0c;这里我也是一样&#xff0c;实现这种设计的方法有很多种&#xff0c;其中就有直接使用case语句将所有可能包含进去编写&#xff0c;这种设计方法是最简单的&…

JavaFX布局-TitledPane

JavaFX布局-TitledPane 常用属性textcontentgraphicexpandedcollapsibleanimated 实现方式Javafxml 提供了一个可折叠的标题栏和一个内容区域内容区域可以嵌套其他布局 常用属性 text 设置标题 titledPane.setText("测试标题");content 内容区域&#xff0c;可以单…

【C++进阶学习】第十弹——哈希的原理与实现——链地址法的原理与讲解

开放地址法&#xff1a;【C进阶学习】第九弹——哈希的原理与实现——开放寻址法的讲解-CSDN博客 前言&#xff1a; 哈希的整体思想就是建立映射关系&#xff0c;前面的开放地址法的讲解中&#xff0c;也对哈希的原理做了详细的讲解&#xff0c;今天就来讲解一下实现哈希的另一…

系统移植(八)u-boot源码解析(未整理)

文章目录 一、分析make <board_name>_defconfig执行过程&#xff08;一&#xff09;1. 1. 分析Makefile文件&#xff0c;分析Makefile文件的规则中目标为"<board_name>_defconfig", &#xff08;二&#xff09;&#xff08;三&#xff09; 二、分析make …

【精通Redis】Redis命令详解

引言 Redis是一个内存数据库&#xff0c;在学习它的内部原理与实现之前&#xff0c;我们首先要做到的就是学会使用&#xff0c;学会其丰富的命令操作。 一、字符串 Redis的字符串类型之前笔者的一篇入门介绍中曾经说过&#xff0c;不是简单的只存人可以阅读的字符串&#xf…

JavaWeb笔记_FilterListener

一.过滤器 1.1 过滤器概述 过滤器主要用来拦截目标资源&#xff08;静态资源或动态资源&#xff09;的请求和响应 &#xff08;类似地铁的安检&#xff09; 我们访问动态或静态资源都要通过URL访问&#xff1a;http://localhost:8080/... 所以过滤器本质上拦截的是URL 1.2 过滤…

select ... for update中锁等级转化

一、结论 select ... for update 除了查询功能&#xff0c;还实现了加锁机制&#xff0c;是一种悲观锁。根据是否使用了主键和索引&#xff0c;决定锁等级是表锁还是行锁。如果采用了&#xff0c;则是行锁&#xff0c;否则是表锁。 二、实例 前提条件&#xff1a;将事务自动…