Codeforces1101F Trucks and Cities 【滑动窗口】【区间DP】
题目分析:
2500的题目为什么我想了这么久。。。
考虑答案是什么。对于一辆从$s$到$t$的车,它有$k$次加油的机会。可以发现实际上是将$s$到$t$的路径以城市为端点最多划分为最大长度最小的$k+1$段。不难发现这样做一定是最优的。
设计DP状态$f[i][j][k]$表示将第$i$座城市到第$j$座城市的路径划分为$k$段。朴素的DP方程是:
$$f[i][j][k] = min(max(f[i][x][k-1],a[j]-a[x])),(which)x \in [i,j]$$
这个DP是$O(n^4)$的,但我们注意到DP状态有单调性。
换句话说,存在一个城市$y$,使得任意$x<y$满足$max(f[i][x][k-1],a[j]-a[x])=a[j]-a[x]$,任意$x>y$满足$max(f[i][x][k-1],a[j]-a[x])=f[i][x][k-1]$。我们考虑的转移只有两个点是有意义的。
对于相同的$i$,$y$的选取仍然具有单调性,所以利用two pointers移动指针可以做到$O(n^3)$
注意:开三维数组会MLE,我们可以滚动一维(甚至可以滚动两维,心动不如行动,试着写一下吧)。
代码:
#include<bits/stdc++.h>
using namespace std; const int maxn = ; int n,m,a[maxn],nxt[maxn]; struct node{int s,t,oil;}; int f[maxn][maxn][];
vector <node> hh[maxn]; void read(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
for(int i=;i<=m;i++){
int s,t,oil,tms;
scanf("%d%d%d%d",&s,&t,&oil,&tms);
tms = min(tms,t-s-)+;
hh[tms].push_back((node){s,t,oil});
}
} void work(){
long long ans = ;
for(int i=;i<=n;i++) for(int j=i;j<=n;j++) f[i][j][] = a[j]-a[i];
for(int k=;k<=n-;k++){
for(int i=;i<hh[k].size();i++)
ans = max(ans,1ll*f[hh[k][i].s][hh[k][i].t][k&]*hh[k][i].oil);
for(int i=;i<=n;i++){
f[i][i][(k+)&] = ; int pts = i;
for(int j=i+;j<=n;j++){
while(f[i][pts][k&] < a[j]-a[pts])pts++;
f[i][j][(k+)&] = min(f[i][pts][k&],a[j]-a[pts-]);
}
}
}
printf("%lld\n",ans);
} int main(){
read();
work();
return ;
}
Codeforces1101F Trucks and Cities 【滑动窗口】【区间DP】的更多相关文章
- codeforces 1101F Trucks and Cities 区间dp+单调优化 好题
题目传送门 题意简述:(来自洛谷) 有n个城市坐落在一条数轴上,第ii个城市位于位置ai. 城市之间有m辆卡车穿行.每辆卡车有四个参数:si为起点编号,fi为终点编号,ci表示每行驶1个单位长 ...
- Codeforces 1101F Trucks and Cities dp (看题解)
Trucks and Cities 一个很显然的做法就是二分然后对于每个车贪心取check, 这肯定会TLE, 感觉会给人一种贪心去写的误导... 感觉有这个误导之后很难往dp那个方向靠.. dp[ ...
- P1886 滑动窗口&&P1440 求m区间内的最小值
声明:下面这两个题就不要暴力了,学一学单调队列吧 推荐博文:https://www.cnblogs.com/tham/p/8038828.html 单调队列入门题 P1440 求m区间内的最小值 题目 ...
- luogu题解 UVA11536 【Smallest Sub-Array】最短set区间&滑动窗口
题目链接: https://www.luogu.org/problemnew/show/UVA11536 题目大意: 给定一个\(N,M,K\),构造这样的数列: \(x[1]=1,x[2]=2,x[ ...
- 洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)
To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每 ...
- 单调队列优化&&P1886 滑动窗口题解
单调队列: 顾名思义,就是队列中元素是单调的(单增或者单减). 在某些问题中能够优化复杂度. 在dp问题中,有一个专题动态规划的单调队列优化,以后会更新(现在还是太菜了不会). 在你看到类似于滑动定长 ...
- CodeForces 701C They Are Everywhere (滑动窗口)
题目链接:http://codeforces.com/problemset/problem/701/C 题意:找到字符串中能包含所有元素的最短字符串长度. 利用“滑动窗口”解题 解题思路: 1. 遍历 ...
- [Leetcode]双项队列解决滑动窗口最大值难题
这道题是从优先队列的难题里面找到的一个题目.可是解法并不是优先队列,而是双项队列deque 其实只要知道思路,这一道题直接写没有太大的问题.我们看看题 给定一个数组 nums,有一个大小为 k 的滑动 ...
- POJ - 2823 Sliding Window (滑动窗口入门)
An array of size n ≤ 10 6 is given to you. There is a sliding window of size kwhich is moving from t ...
随机推荐
- pycharm 中 import requests 报错
一 , 使用Pycharm来抓取网页的时候,要导入requests模块,但是在pycharm中 import requests 报错. 原因: python中还没有安装requests库 解决办法: ...
- c++ 入门之深入探讨拷贝函数和内存分配
在c++入门之深入探讨类的一些行为时,说明了拷贝函数即复制构造函数运用于如下场景: 对象作为函数的参数,以值传递的方式传给函数. 对象作为函数的返回值,以值的方式从函数返回 使用一个对象给另一个对象初 ...
- 黑客帝国效果赏析(包含ES6的语法)
首先,看看效果吧. 代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
- scrapy框架原理学习
Scrapy框架原理: 参考出处:https://cuiqingcai.com/3472.html 整个Scrapy的架构图: Scrapy Engine: 这是引擎,负责Spiders.ItemPi ...
- PS打造油画般的风景人像
- 容器化-Docker实战
导读:本文系统性介绍Docker安装.Docker组件.Docker命令.Dockerfile语法和Docker应用,通过上述介绍使我们已经对docker基本操作有一定了解. 一.前言 本文将系统性的 ...
- Python之random模块
random模块 产生随机数的模块 是Python的标准模块,直接导入即可 import random 1)随机取一个整数,使用.randint()方法: import random print(ra ...
- 后台管理系统之邮件开发(Java实现)
一,功能点 后台管理系统,添加用户时.对注册的新用户邮箱发送初始密码. 二,代码实现 1.Mail实体类 public class Mail { private Set<String> r ...
- Windows和Linux的Jmeter分布式集群压力测试
Windows的Jmeter分布式集群压力测试 原文:https://blog.csdn.net/cyjs1988/article/details/80267475 在使用Jmeter进行性能测试时, ...
- Dockers 学习
Docker镜像操作,有五个常用的命令: a.拉取镜像,后跟镜像仓库名称,如果要指定某个版本,可以带上tag. > docker pull <repo>[:tag] b.列出所有镜像 ...