题目链接:戳我

【问题描述】

有n座山,m只猫和p个工作人员。山从左往右编号为1∼n,山i和i−1之间的距离是di米。

有一天,猫都到山上去玩了:第i只猫会到山hi去,并一直玩到时间ti,之后就在那座山等待工作人员来接它。

每个工作人员的线路都是从1走到n,并带走沿途任意只在等待的猫。工作人员速度为每单位时间1米,不能在山上停留。

例如,假设有两个山丘,d2=1,有一只猫要到山2去,在t=3结束它的玩耍。如果工作人员在时间2或时间3离开山1,则他可以带走这只猫,但如果在时间1离开山1,他就不能带走它。如果工作人员在时间2离开山1,则猫等待他0个时间单位,如果工作人员在时间3离开山1,则猫等待他1个时间单位。

你的任务是安排每个工作人员从1出发的时间(整数,可以是负数),使所有猫的等待时间总和最小。

【输入格式】

第一行三个整数n,m,p,表示山、猫、工作人员的数目。

第二行n−1个整数表示d2∼dn。

后面m行,每行两个数hi,ti。

【输出格式】

一个整数,表示所有猫的等待时间总和的最小值。

【数据规模】

40%的数据,m≤1000,p≤100。

80%的数据,m≤5000,p≤1000。

100%的数据,1≤m≤50000,1≤p≤1000。

对于所有数据,2≤n≤1e5,1≤di≤100,1≤hi≤n,0≤ti≤10e5。


斜率优化。

我们考虑每个猫的结束时间减去它的坐标,就相当于所有猫都在节点1,只是结束的时间不同了。

我们再把这个结束的时间排序一下,就可以设\(dp[i][j]\)表示前i只猫,被j个饲养员带走的最小代价了。

转移方程为:\(dp[i][j]=min{dp[i][j],dp[p][j-1]+node[i].num*(i-p)-(sum[i]-sum[p])}\)

其中\(sum[i]\)表示前i只猫的等待时间前缀和,\(node[i].num\)表示该猫等效于在1节点的开始等待时刻。

然后这个朴素DP是40分的。

现在考虑斜率优化:

把式子移项一下:

\(dp[i][j]+node[i].num*p=dp[p][j-1]+node[i].num*i-sum[i]+sum[p]\)

这就有了\(b+kx=y\)的形式

维护下凸壳即可。

下面这份代码被卡常了??只有90分嘤嘤嘤

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
#define ll long long
using namespace std;
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48); ch=getchar();}
return x*f;
}
ll n,m,p,tail,head;
ll d[MAXN],dis[MAXN],sum[MAXN],dp[50010][1010],q[MAXN];
struct Node{ll p,num;}node[MAXN];
inline double y(int i,int p){return dp[i][p]+sum[i];}
inline double k(int i,int j,int p)
{
if(i==j) return 1e9;
return (y(i,p-1)-y(j,p-1))/(i-j);
}
inline bool cmp(struct Node x,struct Node y){return x.num<y.num;}
int main()
{
n=read(),m=read(),p=read();
for(int i=2;i<=n;i++)
d[i]=read(),dis[i]=dis[i-1]+d[i];
for(int i=1;i<=m;i++)
{
int x;
node[i].p=read(),x=read();
node[i].num=x-dis[node[i].p];
}
sort(node+1,node+1+m,cmp);
for(int i=1;i<=m;i++) sum[i]=sum[i-1]+node[i].num;
memset(dp,0x3f,sizeof(dp));
dp[0][0]=0;
for(int j=1;j<=p;j++)
{
tail=head=0;
for(int i=1;i<=m;i++)
{
while(head<tail&&node[i].num>k(q[head],q[head+1],j)) head++;
dp[i][j]=dp[q[head]][j-1]+node[i].num*i-node[i].num*q[head]-sum[i]+sum[q[head]];
while(head<tail&&k(q[tail-1],q[tail],j)>k(q[tail],i,j)) tail--;
q[++tail]=i;
}
}
printf("%lld\n",dp[m][p]);
return 0;
}

noi.ac #534 猫的更多相关文章

  1. # NOI.AC省选赛 第五场T1 子集,与&最大值

    NOI.AC省选赛 第五场T1 A. Mas的童年 题目链接 http://noi.ac/problem/309 思路 0x00 \(n^2\)的暴力挺简单的. ans=max(ans,xor[j-1 ...

  2. NOI.ac #31 MST DP、哈希

    题目传送门:http://noi.ac/problem/31 一道思路好题考虑模拟$Kruskal$的加边方式,然后能够发现非最小生成树边只能在一个已经由边权更小的边连成的连通块中,而树边一定会让两个 ...

  3. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  4. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  5. NOI.AC NOIP模拟赛 第二场 补记

    NOI.AC NOIP模拟赛 第二场 补记 palindrome 题目大意: 同[CEOI2017]Palindromic Partitions string 同[TC11326]Impossible ...

  6. NOI.AC NOIP模拟赛 第一场 补记

    NOI.AC NOIP模拟赛 第一场 补记 candy 题目大意: 有两个超市,每个超市有\(n(n\le10^5)\)个糖,每个糖\(W\)元.每颗糖有一个愉悦度,其中,第一家商店中的第\(i\)颗 ...

  7. NOI.AC NOIP模拟赛 第四场 补记

    NOI.AC NOIP模拟赛 第四场 补记 子图 题目大意: 一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图.删去第\(i\)条边需要\ ...

  8. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

  9. NOI.AC WC模拟赛

    4C(容斥) http://noi.ac/contest/56/problem/25 同时交换一行或一列对答案显然没有影响,于是将行列均从大到小排序,每次处理限制相同的一段行列(呈一个L形). 问题变 ...

随机推荐

  1. Java源码 HashMap<K,V>

    HashMap类 https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html public class HashMap<K, ...

  2. 虚拟机centos7执行ip addr命令看不到ip地址

    转:https://blog.csdn.net/weixin_43343006/article/details/100094624 进入ect/sysconfig/network-scripts目录在 ...

  3. 【原创】大数据基础之Drill(1)简介、安装及使用

    https://drill.apache.org/ 一 简介 Drill is an Apache open-source SQL query engine for Big Data explorat ...

  4. 高并发之nginx限制

    Nginx限速模块分为哪几种?按请求速率限速的burst和nodelay参数是什么意思?漏桶算法和令牌桶算法究竟有什么不同?本文将带你一探究竟. 我们会通过一些简单的示例展示Nginx限速限流模块是如 ...

  5. 微信小程序常用事件

    bind bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡. bindtap  跳转页面 bindchange  .value 改变时触发 change 事件 bi ...

  6. Python实现串口通信(pyserial)

    pyserial模块封装了对串口的访问,兼容各种平台. 安装 pip insatll pyserial 初始化 简单初始化示例 import serial ser = serial.Serial('c ...

  7. 简单的文件ftp上传

    目录 简单的文件ftp上传 简单的文件ftp上传 server import socket import struct service=socket.socket() service.bind(('1 ...

  8. asyncio:python3未来并发编程主流、充满野心的模块

    介绍 asyncio是Python在3.5中正式引入的标准库,这是Python未来的并发编程的主流,非常重要的一个模块.有一个web框架叫sanic,就是基于asyncio,语法和flask类似,使用 ...

  9. 电子工程师需要了解的SMT贴片质量问题汇总(转)

    点胶工艺中常见的缺陷与解决方法 拉丝/拖尾 拉丝/拖尾是点胶中常见的缺陷,产生的原因常见有胶嘴内径太小.点胶压力太高.胶嘴离PCB的间距太大.贴片胶过期或品质不好.贴片胶粘度太好.从冰箱中取出后未能恢 ...

  10. QTP(5)

    一.检查点 1.位图检查点(Bitmap CheckPoint) (1)作用:主要用于检查UI界面,检查页面布局,包括控件位置.大小.颜色.状态等 (2)确定位图检查点的要素: a.检查哪个控件 b. ...