首页 > 其他分享 >题解 - 修剪草坪

题解 - 修剪草坪

时间:2024-07-09 20:09:04浏览次数:8  
标签:修剪 int 题解 sum back 草坪 max define dq

题目(in 洛谷)题目(in hszxoj)

题目大意

给定 \(n\) 个非负整数 \(a_1 \cdots a_n\)。现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择。
求选出的数字的和最大。

思路简析

一个比较好的思路是反向思考:选择某些间隔小于等于 \(k\) (相邻间隔为 \(0\))的数字,求选择的数字的最小值。

但是我没看明白。

所以顺推并分讨:有两种情况:在前 \(i\) 个数中不选择/选择第 \(i\) 个数时的最大值,分别用 \(f_{i, 0}\) 和 \(f_{i, 1}\) 表示。

\[f_{i, 0} = \max\{f_{i-1, 0}, f_{i-1, 1}\} \]

\[f_{i, 1} = \max_{j=i-k}^{i-1}\{f_{j, 0}+a_{j+1}+\cdots + a_i\} \]

考虑使用前缀和优化,则第二个式子可化简为:

\[\begin{split} f_{i, 1} &= \max_{j=i-k}^{i-1}\{f_{j, 0}+sum[i]-sum[j]\} \\ &= \max_{j=i-k}^{i-1}\{f_{j, 0}-sum[j]\} +sum[i]\} \end{split} \]

这样就是要动态地维护一个区间内的最大值,因此使用单调队列。

每次的维护区间为 \(i-k \sim i-1\),并不包含 \(i\),所以应先弹出不合规的队首,然后更新 \(f_{i, 0}\) 和 \(f_{i, 1}\),最后在保证单调性的同时将当前 \(i\) 加入队列。

CODE

Time complexity:\(\Omega(n)\)。

#include <bits/stdc++.h>
namespace {
#define filein(x) freopen(x".in", "r", stdin)
#define fileout(x) freopen(x".out", "w", stdout)
#define files(x) filein(x), fileout(x)
using namespace std;
#define ll long long
#define db double

const int man = 1e5+10;
}

int n, m;
ll sum[man], f[man][2];
int a[man];
deque <int> dq;
int main () {
#ifndef ONLINE_JUDGE
    files("test");
#endif
    scanf("%d%d", &n, &m);
    dq.push_back(0);
    for (int i = 1; i <= n; ++ i) {
        scanf("%d", a+i), sum[i] = sum[i-1]+a[i];
        while (dq.size() && i-dq.front()>m) dq.pop_front();
        f[i][0] = max(f[i-1][0], f[i-1][1]);
        if(!dq.empty()) f[i][1] = f[dq.front()][0]-sum[dq.front()]+sum[i];
        while (dq.size() && f[i][0]-sum[i]>f[dq.back()][0]-sum[dq.back()]) dq.pop_back();
        dq.push_back(i);
    } printf("%lld", max(f[n][0], f[n][1]));
    return 0;
}

标签:修剪,int,题解,sum,back,草坪,max,define,dq
From: https://www.cnblogs.com/stamorlin/p/18288841/solution-digit_chosen

相关文章

  • Codeforces Round 956 (Div. 2) 部分题解A~C
    A.ArrayDivisibility题目大意构造长度为n的数组,满足:所有j的aj之和可以被k整除,其中j是k的倍数,k的取值为1~n。思路构造序列1->n即可满足条件。代码实现voidsolve(){  lln;cin>>n;  for(inti=1;i<=n;i++)cout<<i<<"";  cout<<"\n"......
  • joi2022_yo2_c 国土分割 (Land Division) 题解
    国土分割(LandDivision)推销我的洛谷博客。题意给定一个\(n\timesm\)的矩阵\(a\),你需要选择在横向或纵向分割至少一次,使得每个分割出来的小矩阵的\(a_{i,j}\)之和相等。数据范围\(1\leqslantn,m\leqslant50\)。\(1\leqslanta_{i,j}\leqslant10^5\)。思......
  • 题解 - 幻象迷宫
    题目in洛谷或题目inCF题目幻象迷宫可以认为是无限大的,不过它由若干个\(N\timesM\)的矩阵重复组成。矩阵中有的地方是道路,用\(\verb!.!\)表示;有的地方是墙,用\(\verb!#!\)表示。起始位置用\(\verb!S!\)表示。也就是对于迷宫中的一个点\((x,y)\),如果\((x\bmodn,y......
  • UVA12342 Tax Calculator 题解
    题目传送门题目大意题目描述某国所得税计算十分复杂。该国政府指定你制作一个自动计算所得税的程序。以下是该国计算所得税的规则:所得税免征额为180000180000......
  • P10719 的题解
    (一)设\(a_{x,y}\)为从\((1,1)(x,y)\)矩形中的\(1\)的数量。然后通过二位前缀和可以\(O(1)\)算。注意到\(1\len,m\le100\)。先确定矩形右下角,对于左上角,先确定在哪一行,再二分在哪一列。(二)AC代码。#include<bits/stdc++.h>#definepbpush_back#definefifirs......
  • 【Py/Java/C++三种语言OD独家2024D卷真题】20天拿下华为OD笔试之【前缀和/固定滑窗】2
    有LeetCode算法/华为OD考试扣扣交流群可加948025485可上欧弟OJ系统练习华子OD、大厂真题绿色聊天软件戳od1441了解算法冲刺训练(备注【CSDN】否则不通过)文章目录题目描述与示例题目描述输入描述输出描述示例一输入输出说明示例二输入输出说明解题思路贪心思想......
  • zxx题单的题解
    https://www.luogu.com.cn/training/168096CF1359ELemma:\(\forallx\in\mathbb{N},\x\bmoda\bmodb=x\bmodb\bmoda\iffa\midb\(a<b)\)Proof:因为\(a<b\),所以\(x\bmoda\bmodb=x\bmoda\)。设\(x=pb+q\),其中\(0<q<b......
  • PostgreSQL的AutoVacuum原理及autovacuum不工作问题解析
    1、AutoVacuum概述PostgreSQL数据库是有数据清理的,有人工执行清理,也有自动清理,但是这2种的清理方式对性能是有不同的影响,特别是OLTP环境中,每次不管是人工清理还是自动清理deadtuple,都会对数据库的IO有明显的影响,基于PostgreSQL的原理每个表中的行会存在多个版本的数据,为了完成......
  • 2024码蹄杯职高省赛第三场初赛全题解
    其实吧对于码蹄杯省赛的话,第三场是一千五百多人,百分之25的获奖率,然后前四百名左右就可以获奖,根据排行来看大概是六题左右,其中大概就四题要点脑子,其余的基本上属于语法题,也就是13题中如果语法没问题的话,九题是很轻松的,因为都是青铜白银题,语法没问题的话就OK的,然后就是一个P序列,......
  • 题解(2024.7.8贪心)
    1.Teleporters(HardVersion)题意:有n+2个位置:0~n+1,给定n个数\(a_1\)~\(a_n\),有以下操作:向左/右移动一格,代价为1。传送回0位置或者n+1位置,记你当前的位置为i,则代价为\(a_i\)。每个位置只能发动一次传送。求最大传送次数思路:因为每次传送都会回到0/n+1号点,所以,到......