题目链接:戳我

【问题描述】

有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. js弹窗返回值详解(window.open方式)

    今天在改公司一个老系统时,碰到了window.open()的这个语法.虽然这个方法有点老,不太用了.所以有点不清楚父级弹框如何获取子级页面返回的值.为了解决这个问题,上网搜了一下.原作者参考网址:ht ...

  2. 记录:初入Java环境部署踩坑

    1.在部署环境之前,先确定大佬们用的哪几种软件,然后依次下载,安装,IDEA, JDK, Tomcat, Maven.    什么是JDK?    JDK是 Java 语言的软件开发工具包,主要用于移 ...

  3. Android-分享多图到微信好友

    /** * 微信分享(多图片) */ private static void shareWeChatByImgList(String kDescription, List<File> im ...

  4. python连接postgres方法

    Python使用PyGreSQL操作PostgreSQL: import pg def operate_postgre_tbl_product(): try: #db = pg.connect(dbn ...

  5. Java反射【四、成员变量的反射和构造的反射】

    获取一个类下所有字段信息 Field[] fs = c.getFields(); 获取所有字段(public) Field[] fs = c.getDeclaredFields(); 获取所有声明字段 ...

  6. 第十章、jupyter入门之pandas

    目录 第十章.jupyter入门之pandas 一.什么是pandas 二.Series 三.基本概念 四.基本运算 五.DataFrame 第十章.jupyter入门之pandas 一.什么是pan ...

  7. 给Eclipse安装MinGW

    @2019-06-30 [小记] 安装完Eclipse后Toolchains只有Cross GCC,下载安装MinGW后添加系统环境变量即可

  8. 需求分析&系统设计

    这个作业属于哪个课程 课程链接 这个作业要求在哪里 作业要求 团队名称 朋友 代打了解一下 这个作业的目标 需求分析&系统设计 一.团队成员的姓名学号列表 学号 姓名 特长 061126 黄天 ...

  9. LoadRunner(1)

    性能测试:HP LoadRunner11 一.初步概念: 1.功能测试:测试产品的功能是否满足功能需求. 如:ATM取款(在线取款)是否成功或转账操作是否成功 -- 一个用户 2.性能测试:测试产品的 ...

  10. PHP通过php-java-bridge调用JAVA的jar包里class类

    正 文:   有的时候我们需要在PHP里调用JAVA平台封装好的jar包里的class类和方法,一般飘易推荐的做法是采用php-java-bridge做桥接,本文就来介绍一下大致的实现方法. 先简单说 ...