题面:CF311B Cats Transport

题解:

  首先我们观察到山与距离其实是没有什么用的,因为对于任意一只猫,我们都可以直接算出如果有一个人要恰好接走它,需要在哪一时刻出发,我们设第i只猫对应的这个时刻为$t_{i}$.

  注意这个$t_{i}$是我自己新定义的,跟题目中的没有关系,下面所写的t都是我现在所定义的t,而跟原题面中的t没有任何关系。

  然后我们对t数组排个序,于是题意转化为了有m只猫,每只猫有一个权值$t_{i}$,如果出发时间大于等于$t_{i}$,则可以接到第i只猫。设出发时间为x,则接到第i只猫时,这只猫会等待$x - t_{i}$的时间。现在有p个人,要求为每个人指定一个时间使得所有猫的等待时间之和最小。

  然后我们继续转化题意。

  观察到每个人相当于会选择一只猫i,然后选择在$t_{i}$时刻出发,恰好接走这只猫,顺便可以接走其他可以被接走的猫。

  为什么是每个人都必须选一只猫呢?

  观察到如果一个人出发,没有任何一只猫是恰好被接到的,所有猫都是等了一会再被接走的,那么这个人为什么不早出发一点,恰好接走一些猫呢?这样不仅可以接走和上一种方案相同的猫,还可以减小等待时间。

  于是现在题意转化为了有m只猫,每只猫有一个权值$t_{i}$。如果第x个人选择了第i只猫,上一个出发的人选了第j只猫,则这个人可以接走[j + 1, i]中的所有猫,并且代价为$\sum_{k = j + 1}^{i}{t_{i} - t_{k}}$。现在有p个人,要求为每个人指定一只猫使得所有猫的等待时间之和最小。

  先化一下式子:(其中s[i]表示$\sum_{k = 1}^{i}{t[k]}$)

  $$\sum_{k = j + 1}^{i}{t_{i} - t_{k}}$$
  $$= \sum_{k = j + 1}^{i}{t_{i}} - \sum_{k = j + 1}^{i}{t_{k}}$$
  $$= (i - j) t_{i} - (s[i] - s[j])$$

  于是我们设f[i][j]表示DP到第i个人,这个人选择了第j只猫的最小代价。

  然后暴力枚举i,j,转移的时候再暴力枚举前一个人选了哪只猫即可。

  但是这样的复杂度是$pm^2$的,观察到我们优化到$pm$就可以过了,又注意到式子中有一个跟i相关的量和一个跟j相关的量的乘积,我们考虑一下斜率优化。

  我们先化一波式子。

$$f[i][j] = f[i - 1][k] + (j - k) t_{j} - (s[j] - s[k])$$
$$\Rightarrow f[i][j] = f[i - 1][k] + jt_{j} - kt_{j} - s[j] + s[k]$$
$$\Rightarrow -s[k] - f[i - 1][k] = -kt_{j} + jt_{j} - s[j] - f[i][j]$$
$$\Rightarrow s[k] + f[i - 1][k] = t_{j}k - jt_{j} + s[j] + f[i][j]$$
  代入y = kx + b可以得到$y = s[k] + f[i - 1][k], x = k, K = t_{j}, b = -jt_{j} + s[j] + f[i][j]$。

  斜优式子已经出来了,现在就是要证明单调性了。

  首先$K = t_{j}$本来就是排好序的,所以从小到大枚举j,所以每次加入的决策点$(x, y)$中的$x = j$肯定是递增的,$t_{j}$肯定也是递增的。

  所以就可以直接上斜优了。  

  然而写的时候发现我对计算几何一无所知,,,凸包维护错了调了好久QAQ

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 110
#define ac 120000
#define LL long long int n, m, p, Head, tail, now;
LL ans;
LL f[AC][ac], d[ac], t[ac], sum[ac], s[ac]; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline void pre()
{
n = read(), m = read(), p = read();
for(R i = ; i <= n; i ++) d[i] = read() + d[i - ];//顺便统计一下前缀和
for(R i = ; i <= m; i ++)
{
LL tmp = read();
t[i] = read() - d[tmp];
}
sort(t + , t + m + );
for(R i = ; i <= m; i ++) sum[i] = sum[i - ] + t[i];//这个要放在排好序之后
} inline void upmin(LL &a, LL b){
if(b < a) a = b;
} inline LL Y(int k){
return sum[k] + f[now][k];
} inline LL cross(int a, int b, int c){//算叉积
LL x1 = a - b, x2 = b - c, y1 = Y(a) - Y(b), y2 = Y(b) - Y(c);
return x1 * y2 - x2 * y1;
} inline LL cal(int x, int k){//算出y - kx,表示b的大小
return Y(x) - t[k] * x;
} inline void work()
{
for(R i = ; i <= m; i ++)
f[][i] = i * t[i] - sum[i];//先算出第一个人的
ans = f[][m];
for(R i = ; i <= p; i ++)//枚举人
{
Head = , tail = , now = i - ;
s[++tail] = ;//0也是一个决策点
for(R j = ; j <= m; j ++)//枚举当前选择的猫
{
while(Head < tail && cal(s[Head + ], j) < cal(s[Head], j)) ++ Head;
int x = s[Head];
f[i][j] = f[i - ][x] + (j - x) * t[j] - sum[j] + sum[x];
while(Head < tail && cross(j, s[tail], s[tail - ]) > ) -- tail;
s[++ tail] = j;
}
upmin(ans, f[i][m]);
}
printf("%lld\n", ans);
} int main()
{
freopen("in.in", "r", stdin);
pre();
work();
fclose(stdin);
return ;
}

CF311B Cats Transport 斜率优化DP的更多相关文章

  1. CodeForces 311 B Cats Transport 斜率优化DP

    题目传送门 题意:现在有n座山峰,现在 i-1 与 i 座山峰有 di长的路,现在有m个宠物, 分别在hi座山峰,第ti秒之后可以被带走,现在有p个人,每个人会从1号山峰走到n号山峰,速度1m/s.现 ...

  2. Codeforces 311B Cats Transport 斜率优化dp

    Cats Transport 出发时间居然能是负的,我服了... 卡了我十几次, 我一直以为斜率优化写搓了. 我们能得出dp方程式 dp[ i ][ j ] = min(dp[ k ][ j - 1 ...

  3. CF331B Cats Transport[斜率优化dp+贪心]

    luogu翻译 一些山距离起点有距离且不同,m只猫要到不同的山上去玩ti时间,有p个铲屎官人要去把所有猫接走,步行速度为1单位每秒,从1走到N座山不停下,必须在猫玩完后才可以把他带走.可以提前出发.问 ...

  4. $CF311B\ Cats\ Transport$ 斜率优化

    AcWing Description Sol 设f[i][j]表示前i个饲养员接走前j只猫咪的最小等待时间. 要接到j猫咪,饲养员的最早出发时间是可求的,设为d: $ d[j]=Tj-\sum_{k= ...

  5. 【题解】Cats Transport (斜率优化+单调队列)

    [题解]Cats Transport (斜率优化+单调队列) # When Who Problem Lang Verdict Time Memory 55331572 Jun/09/2019 19:1 ...

  6. CF-311B Cats Transport(斜率优化DP)

    题目链接 题目描述 小S是农场主,他养了 \(M\)只猫,雇了 \(P\) 位饲养员. 农场中有一条笔直的路,路边有 \(N\) 座山,从 \(1\) 到 \(N\)编号. 第 \(i\) 座山与第 ...

  7. 2018.09.07 codeforces311B. Cats Transport(斜率优化dp)

    传送门 斜率优化dp好题. 对于第i只猫,显然如果管理员想从出发开始刚好接到它,需要在t[i]=h[i]−dist(1,i)" role="presentation" s ...

  8. 斜率优化dp 的简单入门

    不想写什么详细的讲解了...而且也觉得自己很难写过某大佬(大米饼),于是建议把他的 blog 先看一遍,然后自己加了几道题目以及解析...顺便建议看看算法竞赛(蓝皮书)的 0x5A 斜率优化(P294 ...

  9. 动态规划专题(五)——斜率优化DP

    前言 斜率优化\(DP\)是难倒我很久的一个算法,我花了很长时间都难以理解.后来,经过无数次的研究加以对一些例题的理解,总算啃下了这根硬骨头. 基本式子 斜率优化\(DP\)的式子略有些复杂,大致可以 ...

随机推荐

  1. 说一说VIN码识别,车架号识别那些事

    对于有车一族的朋友来说,日常接触比较多的是车牌.行驶证.驾驶证,而知道VIN码/车架号码的比较少. 其实,对于车辆来说,VIN码/车架号码非常重要,它就像人的身份证一样,VIN码/车架号码是车辆唯一的 ...

  2. VIN码识别(车架号识别)在二手车交易中的应用

    最新数据统计,2015年,中国卖出2110万辆新车,相比之下,美国卖出去了1740辆新车.然而,如果算上二手车,美国的汽车市场销量将扩展到4000多辆,而中国的乘用车才不到3000万辆. 销售总额上, ...

  3. 第五模块·WEB开发基础-第2章JavaScript基础

    第1章 JavaScript基础 01-JavaScript历史介绍 02-JavaScript的组成 03-JavaScript的引入方式 04-变量的使用 05-基本数据类型(一) 06-基本数据 ...

  4. Java开发工程师(Web方向) - 04.Spring框架 - 第1章.Spring概述

    第1章.Spring概述 Spring概述 The Spring Framework is a lightweight solution and a potential one-stop-shop f ...

  5. 微服务框架Dubbo与Springcloud的区别

    微服务框架Dubbo与Springcloud的区别 微服务主要的优势如下: 1.降低复杂度 将原来偶合在一起的复杂业务拆分为单个服务,规避了原本复杂度无止境的积累.每一个微服务专注于单一功能,并通过定 ...

  6. 【WXS数据类型】Array

    属性: 名称 值类型 说明 [Array].constructor [String] 返回值为“Array”,表示类型的结构字符串 [Array].length [Number] 返回数组长度 方法: ...

  7. HDU - 6441(费马大定理)

    链接:HDU - 6441 题意:已知 n,a,求 b,c 使 a^n + b^n = c^n 成立. 题解:费马大定理 1.a^n + b^n = c^n,当 n > 2 时无解: 2. 当 ...

  8. spark dataset join 使用方法java

    dataset<Row> df1,df2,df3 //该方法可以执行成功 df3= df1.join(df2,"post_id").selectExpr("h ...

  9. Python replace方法并不改变原字符串

    直接给出结论:replace方法不会改变原字符串. temp_str = 'this is a test' print(temp_str.replace('is','IS') print(temp_s ...

  10. CryptoZombies学习笔记——Lesson3

    第三课就开始深入讲解solidity编程技巧了. chapter1: 智能合约的不变性. 合约一旦部署到以太坊后,就不可更改了,所以从一方面来说,智能合约代码的安全性是如此重要,因为一旦发现你的代码里 ...