codeforces 1101F Trucks and Cities 区间dp+单调优化 好题
题意简述:(来自洛谷)
有n个城市坐落在一条数轴上,第ii个城市位于位置ai.
城市之间有m辆卡车穿行.每辆卡车有四个参数:si为起点编号,fi为终点编号,ci表示每行驶1个单位长度需要消耗的油量,ri表示可以在路途中加油的次数.
当卡车到达一个城市的时候可以将油加满(当然也可以不加),在路中无法加油,但是路途中总加油次数不能超过ri.
所有卡车的油箱都是一样大的,我们称它的容积为V.试求一个最小的V,使得对于所有的卡车都存在一种方案,在路途中任意时刻油箱内的油量大于等于0且路途中总加油次数小于等于ri的情况下从起点城市到达终点城市.
n,m(n≤400,m≤250000)表示城市数量与卡车数量。
思路:
此题学习了洛谷的博客,但洛谷的博客有地方是错误的,导致自闭了许久,自己证明了一波,才走出自闭。
洛谷题解 点这里 但是洛谷题解有错,并且最重要的单调性没有证明。
首先,主体是一个区间DP
设 dp{i,j,k} 为:从第 i 个城市到第 j 个城市分成 k 段,这 k 段中长度最大的一段的最小值
边界: dp{i,j,0}=aj-ai(1≤i≤j≤n)。
状态转移方程
dp {i,j,k}=dp{i,j,k}=min( (max(dp{i,w,k−1},aj−aw))(0<k≤n))( i <= w <= j )
目标:max(ci*dp{si,fi,ri}) i<=m
以上均取自洛谷,并且洛谷的状态转移方程还写错了。上面这个区间dp的时间复杂度是O(n4)的,显然会超时,要进行优化,洛谷题解中说单调性是显然得出的,,然而我证明了好久。
先说两个结果:
1)当 k,i 确定, j 在不断向右移时,对每个 j 取到的 w 具有单调性。
2)同时,当 j 确定时,不同的 w 对应的取值呈“先减后增” 的趋势,
我们先证明第二点,当i j k 确定时,转移方程中 我们设dp{i,w,k−1}为 Aw,aj−aw 为Bw,当w变大时,Aw可能变大,Bw必定变小,所以取值一开始肯定是取Bw的,慢慢变的有可能取Aw,可以想象,这个dp方程一开始肯定是w越大越好,但是当某一个临界点,如果比前面大了,那我们会发现,此时的最大值必定不是Bw,因为Bw<B(w-1),这是必定的。所以最大值是Aw,而w越大,Aw则可能变大,但绝不变小,所以不会有变小的趋势了,证毕。
然后证明第一点,假设j'=j+1,我们先看w是否会前移。发现j变成j'后,只有Bw会变大,Aw是不变的,而越往后的项,最大值取Aw的可能性越大,所以前面的项只会变大,就算当前项变大了,那变大的程度也会和前面的一样,所以取最小值的话当前w必定由于小于w的值。
那么看w是否会后移,由于Bw会变大,Aw只是可能变大,后面的项比前面的项更有可能用到Aw,所以后面的项可能更优,w可能后移,有单调性,证毕。
注意不要开数组不要long long,会爆内存,也不要开太大,开了410*410*410会mle。
#include<bits/stdc++.h>
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int maxn=;
ll ans;
int dp[maxn][maxn][maxn],a[maxn];
int n,m;
int main(){
while(cin>>n>>m)
{
ans=;
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
dp[i][j][]=a[j]-a[i];
}
}
for(int k=;k<=n;k++)
{
for(int i=;i<=n;i++)
{
int w=i;
for(int j=i;j<=n;j++)
{
while(w<j&&max(dp[i][w][k-],a[j]-a[w])>max(dp[i][w+][k-],a[j]-a[w+]))w++;
dp[i][j][k]=max(dp[i][w][k-],a[j]-a[w]);
}
}
}
int s,f,r;
ll c;
while(m--)
{
scanf("%d%d%lld%d",&s,&f,&c,&r);
ans=max(ans,dp[s][f][r]*c);
}
cout<<ans<<endl;
}
}
codeforces 1101F Trucks and Cities 区间dp+单调优化 好题的更多相关文章
- Codeforces 1101F Trucks and Cities dp (看题解)
Trucks and Cities 一个很显然的做法就是二分然后对于每个车贪心取check, 这肯定会TLE, 感觉会给人一种贪心去写的误导... 感觉有这个误导之后很难往dp那个方向靠.. dp[ ...
- HDU3480_区间DP平行四边形优化
HDU3480_区间DP平行四边形优化 做到现在能一眼看出来是区间DP的问题了 也能够知道dp[i][j]表示前 i 个节点被分为 j 个区间所取得的最优值的情况 cost[i][j]表示从i ...
- 【Codeforces 321E / BZOJ 5311】【DP凸优化】【单调队列】贞鱼
目录 题意: 输入格式 输出格式 思路: DP凸优化的部分 单调队列转移的部分 坑点 代码 题意: 有n条超级大佬贞鱼站成一行,现在你需要使用恰好k辆车把它们全都运走.要求每辆车上的贞鱼在序列中都是连 ...
- Educational Codeforces Round 61 F 思维 + 区间dp
https://codeforces.com/contest/1132/problem/F 思维 + 区间dp 题意 给一个长度为n的字符串(<=500),每次选择消去字符,连续相同的字符可以同 ...
- Codeforces Gym100543L Outer space invaders 区间dp 动态规划
原文链接https://www.cnblogs.com/zhouzhendong/p/CF-Gym100543L.html 题目传送门 - CF-Gym100543L 题意 $T$ 组数据. 有 $n ...
- Codeforces 508E Arthur and Brackets 区间dp
Arthur and Brackets 区间dp, dp[ i ][ j ]表示第 i 个括号到第 j 个括号之间的所有括号能不能形成一个合法方案. 然后dp就完事了. #include<bit ...
- POJ 1160 经典区间dp/四边形优化
链接http://poj.org/problem?id=1160 很好的一个题,涉及到了以前老师说过的一个题目,可惜没往那上面想. 题意,给出N个城镇的地址,他们在一条直线上,现在要选择P个城镇建立邮 ...
- UVA - 1632 Alibaba (区间dp+常数优化)
题目链接 设$dp[l][r][p]$为走完区间$[l,r]$,在端点$p$时所需的最短时间($p=0$代表在左端点,$p=1$代表在右端点) 根据题意显然有状态转移方程$\left\{\begin{ ...
- 蓝桥杯:合并石子(区间DP+平行四边形优化)
http://lx.lanqiao.cn/problem.page?gpid=T414 题意:…… 思路:很普通的区间DP,但是因为n<=1000,所以O(n^3)只能拿90分.上网查了下了解了 ...
随机推荐
- keepalived配置
keepalived配置 之前已经安装完成,接下来我们配置keepalived. 假设我的ip地址如下: server1:192.168.0.150 server2:192.168.0.157 vip ...
- CAP理论与HBase
The short summary of the article is that CAP isn't "C, A, or P, choose two," but rather &q ...
- HTML中meta标签的作用与使用
META标签用来描述一个HTML网页文档的属性 META标签可分为两大部分:HTTP-EQUIV和NAME变量. HTTP实例 HTML代码实例中有一项内容是 <meta http-equiv= ...
- Python基础 之 int、bool、str、列表、元组、字典
数据类型 数据类型划分:可变数据类型 不可变数据类型 不可变数据类型:元组.bool.int (本身不可更改).str (可哈希) 可变数据类型:列表list.字典dict .集 ...
- Image Processing, Analysis & and Machine Vision - A MATLAB Companion
Contents目录 Chapter 0: Introduction to the companion book本辅导书简介 Chapter 1: Introduction 简介 Viewing an ...
- ajax data参数
表单 使用serializeArray获取所有: <form id='addForm' action='UserAdd.action' type='post'> <label for ...
- Go语言最佳实践——面向对象
对于接口,应使用组合而非继承的方式扩展: 对于结构体,应定义独立的结构体,而非用嵌套模拟继承. 值接收者和指针接收者: 1.对于不可变类型创建只接受值接收者的方法,而为可变的类型创建接受指针接收者的方 ...
- [转]B+Tree图解
一, M阶B+树的定义(M阶是指一个节点最多能拥有的孩子数,M>2): 图1.1 3阶B+树 (1)根结点只有1个,分支数量范围[2,m]. (2)除根以外的非叶子结点,每个结点包含分支数 ...
- 十四、JS同步异步知识点,重点(Node.js-fs模块补充篇)
(本片文章如果你能耐着性子看我,保证会对同步和异步有一个非常深刻的理解) JavaScript是单线程执行,所谓的单线程呢就是指如果有多个任务就必须去排队,前面任务执行完成后,后面任务再执行.因为Ja ...
- NSCache 缓存
前言 NSCache 是苹果提供的一个专门用来做缓存的类,当内存 "不足" 或超过限制的时候,会自动清理缓存,使用时可以指定缓存的数量和成本. 用法与 NSMutableDicti ...