动态获取某个元素的高度_codeforces 1443D,解法简单,思维缜密的动态规划问题...

bd12ee1201758738f2e1b3664bf0777e.png

大家好,欢迎来到codeforces专题。

今天选择的问题是1443场次的D题,这题是全场倒数第三题,截止到现在一共通过了2800余人。这题的思路不算难,但是思考过程非常有趣,这也是这一期选择它的原因。

链接:https://codeforces.com/contest/1443

a2acdcb965cbbbe00c86a949ce897cb7.png

废话就先说到这里,下面我们就来看题吧。

题意

给定n个整数,对于这n个整数我们可以采取两种操作。第一种操作是在数组左侧选择连续的k个整数减1,第二种操作是选择右侧的连续k个整数减1

比如假设数组是[3, 2, 2, 1, 4],比如我们选择k=2,取最左侧进行操作,那么我们会得到[2, 1, 2, 1, 4]。如果我们选择k=3,再取右侧进行操作,可以得到[2, 1, 1, 0, 3]。

现在我们想要知道,给定这样的数组,我们能否通过这两个操作将数组清空。如果可以输出YES,否则的话输出NO。

样例

首先输入一个整数t(

),表示测试数据组数。

对于每组测试数据,首先输入一个整数n(

),表示数组当中元素的个数。之后输入一行整数
)。可以保证,每一组测试数据的n之和不会超过30000.

bcc63a3de32b4c911d21cf39804c50e4.png

题解

由于我们对于k没有限制,最多我们可以一次对数组内的n个元素全部减一。所以k不是限制我们的因素,最大的限制其实是在元素本身。

我们分析一下会发现,由于数组当中的元素大小不一,这其实是隐形的限制。举个例子,比如[2, 8, 3]。由于我们只能从两侧开始选择元素进行操作,所以由于2和3比较小,会导致我们没有办法把中间的8消除完。当然无法消除的原因可能有好几种,但基本上都是由于元素的大小不一导致的。

首先我们对这个问题进行一个简单的建模,题目当中没有限制执行的次数,所以减一次和减很多次是一样的。我们可以把可以合并的操作合并在一起,理解成执行一次可以减去任意的值。并且我们可以把操作反向理解,把数组当中的值看成是容器,这样我们从数组当中减去值的操作,就可以等价理解成向容器当中输入水流,这样会容易理解一些。

我的第一想法很简单,我们可以求出每个位置能够从左侧和右侧分别获得的最大数值。只要左右两侧能够获取的流量之和大于等于容器的容积,那么就说明我们可以获取到足够的流量灌满所有的容器。

我很快就写出了代码,建了一个二维数组,dp[i][0]表示第i个元素从左侧源头能够获取的最大流量。dp[i][1]表示第i个元素可以从右侧源头获取到的最大流量。由于我们需要保证每个容器存储的体积不能超过容量,所以我们需要很容易得出递推关系。

dp[i][0] = min(dp[i-1][0], a[i])

关系明确了很容易写出代码:

using namespace std;int a[30006], dp[30006][2];int main() {int t, n;scanf("%d", &t);rep(z, 0, t) {scanf("%d", &n);rep(i, 1, n+1) scanf("%d", &a[i]);MEM(dp, 0x3f);// 从左侧递推,获取dp[i][0]rep(i, 1, n+1) {dp[i][0] = min(dp[i-1][0], a[i]);}// 从右侧递推,获取dp[i][1]Rep(i, n, 0) {dp[i][1] = min(dp[i+1][1], a[i]);}bool flag = 1;rep(i, 1, n+1) {// 如果存在某个元素从左右两侧获取的流量之和无法灌满// 则返回NOif (dp[i][0] + dp[i][1] < a[i]) {flag = 0;break;}}puts(flag ? "YES" : "NO");}return 0;
}

但是很遗憾,这样不能AC,因为dp的数组维护的其实是某个位置从左侧和从右侧能够获取的最大值,这是一个理想情况,很有可能这个理想情况是无法实现的。

举个很简单的反例:[2, 4, 2, 4, 2],这些元素左右两边能够获取到的最大流量值都是2,但是这里是有问题的。观察一下会发现数组当中的两个4是无法同时满足的,无法满足的原因是因为中间的2限制了通过的流量。虽然理论上从左往右和从右往左能够通过的流量上限都是2,但是这个上限是无法同时取到的

这个问题用上述的方法是解决不了的,所以需要重新构思。这里我们深入分析会发现一个比较麻烦的点,在于每个点都有两个源头,我们无法确定流量分配。不过这个问题也很好解决,因为左右两边的流量是没有区别的。所以我们可以以某一侧为主,剩余不够的流量再由另一侧补充。

比如我们可以以左侧为主,把左侧能够获取的流量开启到最大,不够地再通过右侧补充。如果右侧的流量无法补充,那么就说明无解。

我们用dp[i][0]记录i位置从左侧获取的流量,dp[i][1]记录i位置从右侧获取的流量。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <string>
#include <map>
#include <set>
#include <algorithm>
#include "time.h"
#include <functional>
#define rep(i,a,b) for (int i=a;i<b;i++)
#define Rep(i,a,b) for (int i=a;i>b;i--)
#define foreach(e,x) for (__typeof(x.begin()) e=x.begin();e!=x.end();e++)
#define mid ((l+r)>>1)
#define lson (k<<1)
#define rson (k<<1|1)
#define MEM(a,x) memset(a,x,sizeof a)
#define L ch[r][0]
#define R ch[r][1]
const int N=1000050;
const long long Mod=1000000007;using namespace std;int a[30006], dp[30006][2], min_need[30006][2], record[30006][2];int main() {int t, n;scanf("%d", &t);rep(z, 0, t) {scanf("%d", &n);rep(i, 1, n+1) scanf("%d", &a[i]);MEM(dp, 0x3f);dp[0][1] = 0;bool flag = 1;rep(i, 1, n+1) {# 如果右侧需要的流量大于容器容积if (dp[i-1][1] > a[i]) {flag = 0;break;}# 左侧能够获取的流量,因为i-1从右侧获取的流量也会经过i,所以需要减去dp[i][0] = min(dp[i-1][0], a[i] - dp[i-1][1]);# 需要从右侧获取的流量需要累加dp[i][1] = dp[i-1][1] + max(0, a[i] - dp[i][0] - dp[i-1][1]);}puts(flag ? "YES" : "NO");}return 0;
}

虽然这个是很简单的动态规划的思想,但是一些细节很容易忽略。比如说i-1位置的右侧流量会流经i以及大于i每一个位置。所以每一个位置的右侧流量是累加的,是越来越大的。只要能够把握住这点,AC是不难的。

总体来说这题的难度不大,对于思维的要求不是很高,但是非常考验思维的缜密性和逻辑性。非常适合用来进行思维锻炼。

今天的文章就到这里,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、关注、转发

原文链接,求个关注

原创 | codeforces 1443D,解法简单,思维缜密的动态规划问题​mp.weixin.qq.com

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

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

相关文章

显卡的优化以提高计算机性能作用,显卡优化,教您如何设置NVIDIA(英伟达)显卡玩游戏性能更高...

多人玩游戏可能都只是在游戏中设置画质选项&#xff0c;比如反锯齿等&#xff1b;而对显卡驱动控制面板中的设置并不关注。其实在显卡驱动面板中设置游戏文件&#xff0c;可以更好的控制和提高游戏画质、性能。那如何设置NVIDIA显卡玩游戏性能更高&#xff1f;下面&#xff0c;…

服务器选购seo优化规则,如何选择有利于SEO优化的空间服务器

之前我们讲过域名&#xff0c;讲过程序&#xff0c;今天我们来讲解空间&#xff0c;其实空间主要影响SEO只有两个方面&#xff0c;一个是速度&#xff0c;一个是稳定性&#xff0c;如果你的空间稳定性不够&#xff0c;经常打不开&#xff0c;百度蜘蛛经常抓取不了&#xff0c;就…

安装npm_Npm安装包的版本号是如何更新的?

点击右上方红色按钮关注“小郑搞码事”&#xff0c;每天都能学到知识&#xff0c;搞懂一个问题&#xff01;大家好&#xff01;我是/小郑搞码事/的小郑今天和大家分享一下关于NPM安装包的版本号是如何更新的问题。版本号&#xff1f;先来看一张图上图就是2.29.1就是安装包Momen…

xp系统如何开启共享服务器,xp系统怎么关闭共享服务 xp系统共享打印机如何设置...

XP系统虽然已经出来很久了&#xff0c;但是仍然还有很多用户在使用&#xff0c;其实不管哪个系统只要电脑可以正常使用就行。很多XP用户在开启共享功能之后&#xff0c;想关闭但是又不知道如何设置&#xff0c;那么下面小编就为大家分享XP系统关闭共享服务的步骤教程&#xff0…

用udp协议通讯时怎样得知目标机是否获得了数据包?_和相亲对象聊天,你属于UDP还是CDP?...

有人说和相亲对象聊天就像ping服务器每发一条消息就像发出一条Ping命令等待对方回复从而得到响应速度结果但是难受的是这个响应速度永远无法做到秒级少点几分钟多则几十分钟甚至几十个小时才有响应有时候真希望对方不要响应了就能判断此处Ping不通从此断了念想...你是否也像这位…

三星w系列vip服务器,高端人士候机专属特权 三星W2017一张行走的VIP卡

原标题&#xff1a;高端人士候机专属特权 三星W2017一张行走的VIP卡17年春运时间为1月13日至2月21日&#xff0c;如今春节假期已过&#xff0c;亿万人开始踏上了离乡之路追寻梦想。每年春运都给交通带来巨大压力&#xff0c;今年为期40天的春运预计全国发送旅客或超29亿人次。铁…

阿酷快捷键怎么使用_必须收藏!Linux用户必须知道的常用终端快捷键

点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐]简介&#xff1a;以下是一些每个 Linux 用户必须使用的键盘快捷键。使用命令行时&#xff0c;这些 Linux 快捷键将提升你的工作效率。你知道什么把专业用户和普通用户分开的吗&#xff1f;掌握键盘快捷键。好的&#xff01…

checkbox ajax 不选中的值,php – 无法通过ajax传递checkbox的值

我有从数据库收到的表&#xff1a;//$id $_SESSION[staff_id];$teamResult getQuarter($leader_id);$count1 0;if (mysqli_num_rows($teamResult) > 0){?>1st Quarterwhile($row mysqli_fetch_array($teamResult)){$staff_id $row[staff_id];$username $row[usern…

3dmax天光渲染设置_【扮家家云渲染效果图】3dmax测试全局照明效果|干货教程...

首先打开场景文件&#xff0c;首先按快捷键8&#xff0c;打开环境和效果控制面板。下面有一个全局照明这样一个选项卡&#xff0c;有染色、级别、环境光三个参数。默认情况下染色为白色&#xff0c;级别为1&#xff0c;环境光为黑色。此时我们可以单击渲染&#xff0c;查看一下…

手写table用ajax遍历,原生js把数据循遍历到前端table

用前端框架去给表格赋值简直不要太容易和简单。但是原生js就会复杂一些了。特别是按钮事件的那个(“ )和 (’)特别让人脑瓜子疼。最近做了一个功能&#xff0c;里面用的就是原生js实现。写在js里面的代码&#xff1a;(用的ajax请求将文件保存到服务器&#xff0c;返回的数据遍历…

centos7下载安装mysql步骤_Linux-centos7安装mysql步骤

Centos7.3 yum安装MySQL5.7.25扩展&#xff1a;在CentOS中默认安装有MariaDB&#xff0c;这个是MySQL的分支&#xff0c;但为了需要&#xff0c;还是要在系统中安装MySQL&#xff0c;而且安装完成之后可以直接覆盖掉MariaDB。1 下载并安装MySQL官方的 Yum Repository[rootlocal…

mysql 常用命令的使用_MySQL基本命令

基操操作命令创建数据库CREATE DATABASE 数据库名&#xff1b;指定要操作的数据库USE 数据库名&#xff1b;创建数据表CREATE TABLE 数据表名&#xff1b;查看数据表SHOW CREATE TABLE 数据表名&#xff1b;使用DESCRIBE语句查看数据表DESCRIBE 数据表名&#xff1b;为数据表重…

python模糊图像清晰化_视频模糊图像处理

随着科学技术的不断发展和进步以及人们的安防意识不断加强&#xff0c;人们对于安防技术的要求越来越高。电子监控在许多领域中都得到了广泛的应用&#xff0c;如交通监控、军事侦查、公共场所安全防范等。清晰的图像能够准确地锁定犯罪证据和犯罪嫌疑人&#xff0c;能够清晰地…

mysql分页 disti_MySql查询性能优化

慢查询判定1.开启慢查询日志记录执行时间超过long_query_time 秒的sql语句2.通过show processlist命令查看线程执行状态3.通过explain解析sql了解执行状态慢查询优化是否向服务器请求列不必要的数据查询不需要的记录(limit)&#xff0c;多表关联返回全部列&#xff0c;总是取出…

python利用matplotlib做饼图_python利用matplotlib库绘制饼图的方法示例

介绍matplotlib 是python最著名的绘图库&#xff0c;它提供了一整套和matlab相似的命令API&#xff0c;十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件&#xff0c;嵌入GUI应用程序中。它的文档相当完备&#xff0c;并且 Gallery页面 中有上百幅缩略图&#xff0…

react同步请求_React中setState同步更新策略

setState 同步更新我们在上文中提及&#xff0c;为了提高性能React将setState设置为批次更新&#xff0c;即是异步操作函数&#xff0c;并不能以顺序控制流的方式设置某些事件&#xff0c;我们也不能依赖于this.state来计算未来状态。典型的譬如我们希望在从服务端抓取数据并且…

DVWA设置mysql_dvwa安装、配置、使用教程(Linux)

一、搭建LAMP环境二、安装DVWA2.1 下载dvwa2.2 解压安装将下载的应用解压到apache默认的主目录/var/www/html&#xff1a;unzip DVWA-master.zip -d /usr/www/html2.3 启用功能dvwa上的漏洞&#xff0c;需要些刻意的配置才能被利用。访问&#xff1a;http://172.0.0.1/dvwa如下…

java jdbc rowset_JAVA基础知识之JDBC——RowSet

RowSet概念在C#中&#xff0c;提供了一个DataSet&#xff0c;可以把数据库的数据放在内存中进行离线操作(读写)&#xff0c;操作完成之后再同步到数据库中去&#xff0c;Java中则提供了类似的功能RowSet.RowSet接口继承自ResultSet接口。与ResultSet相比&#xff0c;RowSet默认…

java 排序原理_简单选择排序算法原理及java实现(超详细)

简单选择排序的原理简单选择排序的原理非常简单&#xff0c;即在待排序的数列中寻找最大(或者最小)的一个数&#xff0c;与第 1 个元素进行交换&#xff0c;接着在剩余的待排序的数列中继续找最大(最小)的一个数&#xff0c;与第 2 个元素交换。以此类推&#xff0c;一直到待排…

ckeditor java 上传_CKEditor粘贴图片自动上传到服务器(Java版)

环境&#xff1a;java,springmvc,ckeditor,tomcat,maven情况&#xff1a;在做项目的时候发现本地图片粘贴到ckeditor中&#xff0c;img标签的src中的值是“data:image/png;base64,”开头的&#xff0c;后面会跟一串字符串&#xff0c;图片越大字符串越长&#xff0c;这样的图片…