摆渡车(noip2018 pj t3)

摆渡车(题目和测试右转 洛谷P5017)

做法:dp+各种优化(剪枝)

这道题考场上看了一脸懵逼...第一眼看这 tm 不是个一维dp吗...结果按着这个朦胧的思路,删删改改约莫0.5h,终于过了样例,然后一测大样例...GG了。冥思苦想了1h,最终放弃了 (感谢这白费的1.5h,迫使我T4打了个暴力,结果AC了...

言归正传

考试完后,参考了各种题解,WA了N/A次,终于AC了这道毒瘤题,艰难的AC历程...

(〇)引子

首先来阐明一下题意:在一条数轴上有n个点,然后要求将这条数轴分为若干段(左开右闭的区间),要求:每段的两个端点之间的距离必须 >= m,求分段的最小总费用。

费用定义为:若一个点k在区间 ( j , i ] ,则这个点的费用为 i - k (可能一个位置上有多个点)

总费用定义为:所有点的费用和即为总费用

 

(一)如何拿分(暴力?)

讲解完题意,接下来我们要研究一个很重要的问题:如何拿分?

先看 30% 的数据:

n20,  m2,  0ti100

看着 ti 的大小很容易想到用一维数组 f[i] 表示在第 i 分钟发车的最小费用。

然后,这TM不是个一维线性dp吗?

我们可以枚举一个 j ,即枚举前一次是在哪里发车的,这样我们便得到了状态转移方程:

这样一来,时间复杂度就是  30%的数据是可以过的。

 

(二)如何拿中分(不高也不低的分

看一下50%的数据:

n ≤ 500,  m ≤ 100, 0 ≤ ti ≤ 10^4

nt^2的时间复杂完全过不了50%得数据,怎么办呢

通过观察(一)的状态转移方程,可以发现枚举一个k实际上是没必要的,可以用前缀和优化:

将等车人到达的时间用数组存起来,peo[ i ]表示在 0 到 i 分钟内等车人的数量,cost[ i ]表示在 0 到 i 分钟所有等车人到达时间的累积(即将 1 到 i 分钟内到达的等车人的到达时间累加起来)

就可以得到状态转移方程

分析一下时间复杂度:因为只枚举了 i 和 j ,所以时间复杂度降低为

50%的数据在 “少爷机” 上是稳稳的。

程序段:

 

1 for(int i=1; i<t+m; i++)
2 {
3     f[i] = i*peo[i] - cost[i]; 
4     for(int j=0; j<=i-m; j++)
5         f[i] = min(f[i], f[j]+(peo[i]-peo[j])*i-(cost[i]-cost[j]));
6 }

 

 

 

 

(三)如何拿高分(不是满分,考场上的高分

自然是优化啦。问题来了,如何优化。

先看看70%的数据范围:

n500m100ti4×10^6

很明显,t^2的时间复杂的是肯定超的。而 i 是这个状态转移方程的状态,必须要枚举,只能从 j 下手,优化这个动态规划了。

j 如何优化呢?其实,仔细想一想,很容易发现,j 没有必要从 0 枚举到 i-m,换句话说,从0到 i-m 的这段区间内,有很多状态是无用的,即这些状态一定不能构成当前 f[i] 的最优解,真正有用的只有区间 ( i-m-m+1, i-m ]。如何证明呢?

先贴一幅图:

 

观察上图可以发现:

当 j 在 ( R, i )中时,摆渡车回来的时间一定大于 i ,不满足状态 f[i] 的定义,舍去。

当 j 在 ( ?, L ]中时,一定可以多发一次车,使摆渡车回来的时间小于等于 i,这样得到的花费一定小于等于只发一次车的情况。因此,也可以省去。

最后,我们发现,j 只能在区间 ( L, R ] 之间才能得到最小花费,即 j 只有 m-1 种情况

于是,状态转移方程不变,j 的枚举范围改变,时间复杂度降为

70%的数据稳稳地过,甚至在 “少爷机” 上面的 score 可能 100 ( 最起码分数在70以上 )。

程序段:

 

1 for(int i=1; i<t+m; i++)
2 {
3     f[i] = i*peo[i] - cost[i]; 
4     for(int j=max(i-m-m+1,0); j<=i-m; j++)
5         f[i] = min(f[i], f[j]+(peo[i]-peo[j])*i-(cost[i]-cost[j]));
6 }

 

 

(四)70+太低了如何拿满分

老样子,再来看一下数据范围(终极boss来了):

n500m1000ti4×10^6

m的范围变回 100 了,tm的时间复杂度好方,肿么办!!!

别着急,先来分析一下数据范围:

可以发现,ti 达到了4*10^6 ,然鹅 n 却还是500,不难想象,如果将 ti 看做一条线段,上面有 4*10^6个整点,然后取其中的500个点标记,标记的点一定是非常离散的。

 同样的道理,在如此之大的 ti 中,一定有很多区间是没有等车人的(无用的区间),但是仍然无用地枚举了m次,时间复杂度大大增加。

这时候,我们只需要加一个小小的剪枝,判断当前枚举的 i 点到 i-m 中是否有人,如果没有人的话,就没有必要进行多一次的循环了(因为再发多一次车对答案没有影响,毕竟没人),只需要将 f[i] 赋值为 f[i-m],然后continue即可。

经过某神犇的证明,经过这次剪枝后,实际枚举的点只有 nm 个,时间复杂度降为(当然还有一个常数 t 被我忽略了)

100%的数据跑得飞快……

程序段:

 

1 for(int i=1; i<t+m; i++)
2 {
3     if(i>=m and peo[i]-peo[i-m] == 0) {f[i] = f[i-m]; continue;}
4     f[i] = i*peo[i] - cost[i]; 
5     for(int j=0; j<=i-m; j++)
6         f[i] = min(f[i], f[j]+(peo[i]-peo[j])*i-(cost[i]-cost[j]));
7 }

 

 

(五)答案在哪?

终于到最后一步了,显而易见,answer一定在最大的时间后面(废话),只需要从 t 枚举到 t+m-1 取一个最小值即可。

注意:

代码中的 t 和 (五)中的 t 含义相同,都是最后到的那个人的到达时间。

 

ps:终于写完了,这个思路是参考了某神犇的(@Sooke),再加上了自己的一些理解,希望能有帮助。

 

转载于:https://www.cnblogs.com/GDOI2018/p/9994768.html

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

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

相关文章

关于树的冷知识

1、为什么冬天树干刷白漆&#xff1f; 刷的是是石灰水&#xff0c;主要成分是石灰乳,还有食盐,大豆粉,石榴合剂。 好处一、石灰具有一定的杀菌、杀虫作用&#xff0c;可以杀死寄生在树干上的一些越冬的真菌、细菌和害虫。 好处二、由于害虫一般都喜欢黑色、航脏的地方&#x…

乐玩自动化测试模块_自动化测试模型(一)自动化测试模型介绍

一个自动化测试框架就是一个集成体系&#xff0c;在这一体系中包含测试功能的函数库&#xff0c;测试数据源&#xff0c;测试对象标准&#xff0c;以及各种可重用的模块。自动化测试在发展过程中经历了以下几个阶段&#xff0c;模块驱动测试&#xff0c;数据驱动测试及对象驱动…

linux特殊权限位之setuid、setgid和sticky

我们登陆到系统之后,创建一个普通文件或者目录的时候,会有一个默认的权限。普通文件是644,目录文件是755,想必大家都知道这个是由umask这个值决定的。我们可以直接执行umask命令查看&#xff0c;linux系统默认的umask值是0022。想改变创建文件默认的权限&#xff0c;我们直接修…

js获取当前时间,并实时更新

可以使用JavaScript的Date()对象来获取当前时间&#xff0c;并使用setInterval()函数实现实时更新。 以下是一个示例代码&#xff1a; <p id"time"></p>function updateTime() {var now new Date();var hours now.getHours();var minutes now.getMi…

11.23日常

整理相关资料&#xff0c;阅读c#课本转载于:https://www.cnblogs.com/JL3Peanut/p/10032318.html

python requests 10041报错_pythonrequests返回unicode异常消息(或如何设置请求区域设置)...

您可以尝试os.strerror&#xff0c;但它可能不会返回任何内容或相同的非英语字符串。在ENGLISH_WINDOWS_SOCKET_MESSAGES {10004: "Interrupted function call.",10013: "Permission denied.",10014: "Bad address.",10022: "Invalid argu…

深度学习(花书)

1.英文主页http://www.deeplearningbook.org/lecture_slides.html 2.中文主页https://github.com/exacity/deeplearningbook-chinese 在线阅读https://exacity.github.io/deeplearningbook-chinese/转载于:https://www.cnblogs.com/Eufisky/p/10010046.html

表面配准论文1--基于高阶图匹配方法的稠密表面配准

Dense Non-rigid Surface Registration Using High-Order Graph Matching 一.摘要提出高阶图匹配方程来解决非刚性表面配准问题&#xff0c;单阶项描述了几何和外观相似性&#xff08;曲率和纹理&#xff09;&#xff0c;高阶项对内部嵌入能量&#xff08;intrinsic embedding …

Apache Spark软件包,从XML到JSON

Apache Spark社区为扩展Spark付出了很多努力。 最近&#xff0c;我们希望将XML数据集转换为更易于查询的内容。 我们主要对每天进行的数十亿笔交易之上的数据探索感兴趣。 XML是一种众所周知的格式&#xff0c;但是有时使用起来可能很复杂。 例如&#xff0c;在Apache Hive中&a…

js中几种实用的跨域方法原理详解

这里说的js跨域是指通过js在不同的域之间进行数据传输或通信&#xff0c;比如用ajax向一个不同的域请求数据&#xff0c;或者通过js获取页面中不同域的框架中(iframe)的数据。只要协议、域名、端口有任何一个不同&#xff0c;都被当作是不同的域。 下表给出了相对http://store.…

python中matplotlib画图_Python-matplotlib画图(莫烦笔记)

这个是我对于莫烦老师的matplotlib模块的视频做的一个笔记。1.前言Matplotlib是一个python的 2D绘图库&#xff0c;它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。通过Matplotlib&#xff0c;开发者可以仅需要几行代码&#xff0c;便可以生成绘图&#xff0c…

js词法分析

javascript词法分析函数在运行的瞬间&#xff0c;生成一个活动对象&#xff08;Active Object&#xff09;&#xff0c;简称AO&#xff1b;具体分为两个阶段&#xff1a;一.分析阶段JavaScript代码运行前有一个类似编译的过程即词法分析&#xff0c;词法分析主要有三个步骤&…

如何使一维数组一行一行的输出成二维数组的格式

以9个元素的数组为例&#xff0c;输出3x3的格式 基本思想是对每一个元素的index进行检查&#xff0c;当index是3,6,9等可以被3整除的数时&#xff0c;在打印它们之前&#xff0c;先打印一个\n。注意0也可以被3整除&#xff0c;但是此时不打印\n&#xff0c;所以要加上i>0的…

python我想对你说_python学习第3天-----字典、解构

1.字典1)定义&#xff1a;查找速度快&#xff0c;效率高&#xff1b;用{}括起来&#xff0c;内部使用key:value的形式来保存数据&#xff1b;键值对是无序的&#xff0c;不是按照定义的方式保存数据的(类似于json文件)&#xff0c;例如&#xff1a; {jay:周杰伦,jj::林俊杰}注&…

bms_output.put_line使用方法

https://blog.csdn.net/sxww321/article/details/4020300转载于:https://www.cnblogs.com/diyunpeng/p/10022923.html

linux 权限掩码 umask

一 权限掩码umaskumask是chmod配套的&#xff0c;总共为4位&#xff08;gid/uid,属主&#xff0c;组权&#xff0c;其它用户的权限&#xff09;,不过通常用到的是后3个&#xff0c;例如你用chmod 755 file&#xff08;此时这文件的权限是属主读(4)写(2)&#xff0b;执行(1),同…

ant 构建_有用的Ant构建标签

ant 构建问题&#xff1a; 如何在ant文件中执行以下任务&#xff1f; 制作zip文件。 运行命令。 将文件复制到远程计算机。 在远程Linux机器上运行命令。 打开输入框并响应输入值。 拨打蚂蚁电话。 答案&#xff1a; 1.制作zip文件&#xff1a; 以下是在ant中制作zip文…

C++文件交互(txt、excel)

前些天完成了计算机视觉大作业&#xff0c;《基于双目立体视觉的深度图像生成》&#xff0c;虽然刚开始觉得作业很难&#xff0c;也没找到现成的程序&#xff0c;但做到最后还是学到很多知识&#xff0c;get到很多技能&#xff0c;现在一一总结下来。 1、C输出数据到txt 包含…

基类数组存放派生类_永远不要将派生类数组赋值给基类类型指针

C.152: Never assign a pointer to an array of derived class objects to a pointer to its baseC.152:永远不要将派生类数组的指针赋值给基类指针Reason(原因)Subscripting the resulting base pointer will lead to invalid object access and probably to memory corruptio…