CF1918 D. Blocking Elements [二分+数据结构优化dp]

传送门:CF

[前题提要]:二分+数据结构优化dp,赛时想到了二分,想到了dp,想到了应该是某种双log的做法,但是硬是想不出正确的dp的定义,看了讲解感觉dp方程的定义还是很典的,dp题写的少是这样的…


题目要求我们输出满足所有去掉的数字和以及区间段和的最大值的最小值.不难想到使用二分答案.

考虑二分答案,此时我们的问题变成了,判断当前是否存在方案能满足我们二分出来的 m i d mid mid.很多人应该会直接想贪心吧,直接贪,发现样例二过不去,然后我当时的想法是用一种类似反悔贪心的想法,踢出前缀的某个数,但是想想做法十分麻烦,似乎不太可做.

当时我看了一下数据范围和时限, 1 e 5 , 4 s 1e5,4s 1e5,4s,很显然要么是一种 n n n\sqrt{n} nn 算法,要么是一种双 l o g log log做法,想想了根号算法有哪些,感觉D题不太可能出根号数据结构,根号分治也没法用.所以应该是一种双 l o g log log做法,而且二分答案用了一个 l o g log log,所以 c h e c k check check应该是一个 l o g log log算法.

然后赛时我想了想dp做法.当时在想返回贪心的时候已经有一种感觉了,就是假设当前枚举的位置是 i i i,那么以 i i i往左的区间和是单调递增的,这个单调性感觉有点用.但是当时在想一个位置有两种状态,留下或者删除,那么这两个状态该怎么转移呢.想了想留下的情况实在是难以转移.所以就放弃然后三题下班了.


o k ok ok,现在讲一下正解:
考虑定义 d p [ i ] dp[i] dp[i]表示删除第 i i i位且前 i i i位合法的最小删数和.
诶,此时会发现留下的状态为什么不记录呢,我感觉这一步是这道题的关键步骤(但是感觉这个想法应该很典,可能是我dp写太少了).此时我们会发现那么dp[n+1]就表示删数第n+1位前n位合法的最小删数和,a[n+1]=0.哇,此时我们的 d p [ n + 1 ] dp[n+1] dp[n+1]就是最终的答案,我们根本不需要记录留下的状态!

P S : PS: PS:其实细想一下这个定义的正确性,会发现其实就是枚举最后一段合法划分区间,这种类似的枚举思想在计数题中其实经常出现.

dp定义出来以后,这道题就没什么难度了.转移方法就是使用上述讲过的单调性,考虑当前 i i i位置我们删除,那么我们可以二分/双指针来轻松维护出能转移的左端点.这里存在一个小贪心可能需要稍微提一下,假设区间 [ l , i − 1 ] [l,i-1] [l,i1]的区间和满足我们的 m i d mid mid,那么显然此时的转移应该是直接转,因为没有必要在区间里再删除一个数.
找出左右端点之后只需要找到最小的dp值,然后 d p [ i ] = M i n ( d p [ j ] ) + a [ i ] dp[i]=Min(dp[j])+a[i] dp[i]=Min(dp[j])+a[i]直接转移.维护区间最小值这种RMQ问题可以使用单调队列/优先队列/数据结构等维护,此处不在赘述.作者在代码中使用的是线段树.


下面是具体的代码部分:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define root 1,n,1
#define ls (rt<<1)
#define rs (rt<<1|1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
inline ll read() {ll x=0,w=1;char ch=getchar();for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') w=-1;for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';return x*w;
}
inline void print(__int128 x){if(x<0) {putchar('-');x=-x;}if(x>9) print(x/10);putchar(x%10+'0');
}
#define maxn 1000000
#define int long long
const double eps=1e-8;
#define	int_INF 0x3f3f3f3f
#define ll_INF 0x3f3f3f3f3f3f3f3f
struct Segment_tree{int l,r,mn;
}tree[maxn<<2];
void build(int l,int r,int rt) {tree[rt].l=l;tree[rt].r=r;tree[rt].mn=0;if(l==r) {return ;}int mid=(l+r)>>1;build(lson);build(rson);tree[rt].mn=min(tree[ls].mn,tree[rs].mn);
}
void update(int pos,int rt,int val) {if(tree[rt].l==pos&&tree[rt].r==pos) {tree[rt].mn=val;return ;}int mid=(tree[rt].l+tree[rt].r)>>1;if(pos<=mid) update(pos,ls,val);else update(pos,rs,val);tree[rt].mn=min(tree[ls].mn,tree[rs].mn);
}
int query(int l,int r,int rt) {if(tree[rt].l==l&&tree[rt].r==r) {return tree[rt].mn;}int mid=(tree[rt].l+tree[rt].r)>>1;if(r<=mid) return query(l,r,ls);else if(l>mid) return query(l,r,rs);else return min(query(l,mid,ls),query(mid+1,r,rs));
} 
int a[maxn];int n;int dp[maxn];
//dp[i]表示删除第i位且前i位合法的最小删数和
//那么dp[n+1]就表示删数第n+1位前n位合法的最小删数和,a[n+1]=0;
int sum[maxn];
int check(int mid) {build(1,n+2,1);for(int i=1;i<=n+1;i++) dp[i]=0;for(int i=1;i<=n+1;i++) {int l=0,r=i-1;int pos=0;while(l<=r) {int MID=(l+r)>>1;if(sum[i-1]-sum[MID]<=mid) {pos=MID;r=MID-1;}else {l=MID+1;}}dp[i]=query(pos+1,i,1)+a[i];update(i+1,1,dp[i]);}return dp[n+1]<=mid;
}
signed main() {int T=read();while(T--) {n=read();for(int i=1;i<=n;i++) {a[i]=read();sum[i]=sum[i-1]+a[i];}int l=1,r=1e14;int ans=-1;while(l<=r) {int mid=(l+r)>>1;if(check(mid)) {ans=mid;r=mid-1;}else {l=mid+1;}}cout<<ans<<endl;//clearfor(int i=0;i<=n;i++) {a[i]=sum[i]=0;}}return 0;
}

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

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

相关文章

meson、ninja编译dpdk

解压目录meson编译dpdk meson buildmeson编译dpdk debug版 meson setup --buildtypedebug debugbuildmeson编译使用静态库&#xff0c;编译example meson .. --prefix/usr/local --buildtypedebugoptimized --default-librarystatic -Dexamplesallninja编译 ninjaninja安装…

springboot-前后端分离——第二篇

本篇主要介绍一个发送请求的工具—postman&#xff0c;然后对请求中的参数进行介绍&#xff0c;例如简单参数、实体参数、数组参数、集合参数、日期类型参数以及json类型参数&#xff0c;对这些参数接收进行总结。最后对响应数据进行介绍&#xff0c;使用统一响应结果返回浏览器…

在JAVA中如何使用ASCLL码

在Java中&#xff0c;你可以直接使用ASCII码来表示和处理字符。ASCII&#xff08;American Standard Code for Information Interchange&#xff0c;美国信息交换标准代码&#xff09;是一种计算机编码系统&#xff0c;用于表示英文字符为数字。ASCII码使用7位或8位二进制数表示…

轮转数组[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个整数数组nums&#xff0c;将数组中的元素向右轮转k个位置&#xff0c;其中k是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,…

Golang k8s相关yaml包的区别

问题背景 大概是因为 k8s 定义了一些特殊的数据类型&#xff0c;所以 k8s 对象 yaml 序列化时与其它 yaml 包结果不同。 源代码 package mainimport ("log""os""github.com/ghodss/yaml"yamlv2 "gopkg.in/yaml.v2"yamlv3 "k8s…

八数码问题dfs

import java.util.*;public class Main{static String end "12345678x";public static void swap(char[] arr,int x,int y){char temp arr[x];arr[x] arr[y];arr[y] temp;}public static int bfs(String start){//key:String 存放12345678x这种格式的字符//value…

基金分红方式:现金分红与红利再投

基金是一种集合性投资工具&#xff0c;通过基金&#xff0c;投资者可以间接持有多种证券组合&#xff0c;包括股票、债券等。在投资基金时&#xff0c;投资者通常会关注基金的收益分配方式&#xff0c;其中现金分红和红利再投是两种常见的方式。 一、什么是基金分红 基金分红…

Centos7安装原生Nginx并配置反向代理

一、背景 当我的应用程序需要集群化部署之时&#xff0c;必然需要一个反向代理&#xff0c;当然Nginx的大名&#xff0c;这里不做更多的介绍了&#xff0c;这里介绍一下Nginx常用的四大阵营 1 Ngnix 原生版本 nginx news 2 Nginx Plus 商用版&#xff08;收费的&#xff09…

Android 12系统源码_页面管理(四)获取系统当前最上层的Activity信息

前言 很多应用开发人员&#xff0c;在日常开发过程中&#xff0c;经常会遇到一些需求&#xff0c;例如需要知道当前最上层的Activity是哪个&#xff0c;并结合这个Activity的名称来完成一些特定场景的需求。最简单的方法&#xff0c;是在创建Activity的时候将该Actvity存储到一…

20240127在ubuntu20.04.6下配置whisper

20240131在ubuntu20.04.6下配置whisper 2024/1/31 15:48 首先你要有一张NVIDIA的显卡&#xff0c;比如我用的PDD拼多多的二手GTX1080显卡。【并且极其可能是矿卡&#xff01;】800&#xffe5; 2、请正确安装好NVIDIA最新的驱动程序和CUDA。可选安装&#xff01; 3、配置whispe…

经典左旋,指针面试题

今天给大家带来几道面试题&#xff01; 实现一个函数&#xff0c;可以左旋字符串中的k个字符。 例如&#xff1a; ABCD左旋一个字符得到BCDA ABCD左旋两个字符得到CDAB 我们可以先自己自行思考&#xff0c;下面是参考答案&#xff1a; 方法一&#xff1a; #define _CRT_SEC…

2024美赛数学建模D题思路+模型+代码+论文(持续更新)

2024美赛数学建模A题B题C题D题E题F题思路模型代码论文&#xff1a;开赛后第一时间更新&#xff0c;获取见文末名片 组队环节&#xff1a; 美赛最多是3个人参赛&#xff0c;一般的队伍都是由三人组成&#xff08;当然如果你很大佬也可以一个人参赛&#xff09;&#xff0c;队伍…

力扣hot100 划分字母区间 贪心 思维 满注释版

Problem: 763. 划分字母区间 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 代码随想录 复杂度 时间复杂度: O ( n ) O(n) O(n) 空间复杂度: O ( n ) O(n) O(n) Code class Solution {public List<Integer> partitionLabels(String s){// 创建哈希…

【nginx实战】通过nginx实现http请求的keep alive长连接

文章目录 一. 概述二. nginx与client的长连接1. keepalive_timeout指令2. keepalive_requests指令场景分析 三. 保持和server的长连接1. location设置场景分析 2. upstream设置3. 场景分析场景1&#xff1a;场景2&#xff1a;场景3&#xff1a; 一. 概述 当使用nginx作为反向代…

神经网络的一些常规概念

epoch&#xff1a;是指所有样本数据在神经网络训练一次&#xff08;单次epoch(全部训练样本/batchsize)/iteration1&#xff09;或者&#xff08;1个epochiteration数 batchsize数&#xff09; batch-size&#xff1a;顾名思义就是批次大小&#xff0c;也就是一次训练选取的样…

Vue中使用定义的函数时,无法访问到data()里面的数据

const translateItems1 () > {this.translatedItems this.items1.map(item > {return {...item,label: this.$t(item.labelKey)};}); items1是我们data()里面的数据&#xff0c;无法访问到 解决办法 把箭头函数替换为普通函数 const translateItems1 function() {th…

EXCEL VBA实现重复字段出现次数并列显示

EXCEL VBA实现重复字段出现次数并列显示 Sub dotest() Dim arr, dApplication.ScreenUpdating FalseSet d CreateObject("Scripting.Dictionary")With Sheets("Sheet2")r .Cells(.Rows.Count, "a").End(xlUp).Rowarr .[a1].Resize(r, 1)En…

HTML标签 - 1

文章目录 HTML标签简介HTML书写规范常见网页制作软件常用标签结构标签排版标签标题标签容器标签字体标签文本格式化标签列表标签图片标签 HTML标签 简介 一门使用标记标签来描述网页&#xff0c;展示信息给用户的语言。 超文本标记语言&#xff08;Hyper Text Markup Langua…

保障网络环境清朗与安全:非法关键字过滤的重要性与实现方法

在当今数字化时代&#xff0c;网络已经成为人们获取信息、交流思想的主要平台。然而&#xff0c;随着互联网的普及&#xff0c;一些不法分子也越发倾向于通过网络渠道散布有害信息。为了维护网络环境的清朗与安全&#xff0c;非法关键字过滤技术应运而生。本文将探讨非法关键字…

WMS系统与电商平台快速拉通库存数量

什么是WMS系统 WMS系统是指仓储管理系统&#xff08;Warehouse Management System&#xff09;。它是一种用于管理和控制仓库运营的软件系统。WMS系统通过集成信息技术&#xff0c;提供仓库内货物的存储、出入库、库存管理、订单处理等功能&#xff0c;优化仓库的运作效率和准…