noi.ac #534 猫
题目链接:戳我
【问题描述】
有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 猫的更多相关文章
- # NOI.AC省选赛 第五场T1 子集,与&最大值
NOI.AC省选赛 第五场T1 A. Mas的童年 题目链接 http://noi.ac/problem/309 思路 0x00 \(n^2\)的暴力挺简单的. ans=max(ans,xor[j-1 ...
- NOI.ac #31 MST DP、哈希
题目传送门:http://noi.ac/problem/31 一道思路好题考虑模拟$Kruskal$的加边方式,然后能够发现非最小生成树边只能在一个已经由边权更小的边连成的连通块中,而树边一定会让两个 ...
- NOI.AC NOIP模拟赛 第五场 游记
NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...
- NOI.AC NOIP模拟赛 第六场 游记
NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...
- NOI.AC NOIP模拟赛 第二场 补记
NOI.AC NOIP模拟赛 第二场 补记 palindrome 题目大意: 同[CEOI2017]Palindromic Partitions string 同[TC11326]Impossible ...
- NOI.AC NOIP模拟赛 第一场 补记
NOI.AC NOIP模拟赛 第一场 补记 candy 题目大意: 有两个超市,每个超市有\(n(n\le10^5)\)个糖,每个糖\(W\)元.每颗糖有一个愉悦度,其中,第一家商店中的第\(i\)颗 ...
- NOI.AC NOIP模拟赛 第四场 补记
NOI.AC NOIP模拟赛 第四场 补记 子图 题目大意: 一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图.删去第\(i\)条边需要\ ...
- NOI.AC NOIP模拟赛 第三场 补记
NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...
- NOI.AC WC模拟赛
4C(容斥) http://noi.ac/contest/56/problem/25 同时交换一行或一列对答案显然没有影响,于是将行列均从大到小排序,每次处理限制相同的一段行列(呈一个L形). 问题变 ...
随机推荐
- 并不对劲的bzoj4945:loj2305:uoj317:p3825[NOI2017]游戏
题目大意 2-SAT,其中有\(d\)(\(d\leq 8\))个点是\(3-SAT\). 题解 枚举\(d\)个点不取三个中(假设三个为\(a,b,c\))的哪一个,然后整体变成做\(2-SAT\) ...
- 版本控制工具SVN学习
教学视频链接:https://edu.aliyun.com/course/83?spm=5176.10731334.0.0.778e6580zC0Ri0 版本控制工具SVN学习 1,SVN的简介 在实 ...
- MVC4学习要点记二
一.分页(PagedList.MVC)1.安装PagedList.MVCPM>install-package PagedList.mvc 2.控制器中使用PagedList 3.csht ...
- [git] Updates were rejected because the tip of your current branch is behind its remote counterpart.
场景 $ git push To https://github.com/XXX/XXX ! [rejected] dev -> dev (non-fast-forward) error: fai ...
- jvm之java类加载机制和类加载器(ClassLoader),方法区结构,堆中实例对象结构的详解
一.类加载或类初始化:当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.连接.初始化3个步骤来对该类进行初始化.如果没有意外,JVM将会连续完成3个步骤. 二.类加载时机: 1 ...
- JavaScript和Java是不同公司开发的不同产品
首先,JavaScript和Java是不同公司开发的不同产品.javascript是Netscape的产品.它的目的是扩展Netscape Navigator功能,开发一种可以嵌入到网页中的对象和事件 ...
- S=a+aa+aaa...(js)
/*求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字. 例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制.*/ let readline = ...
- Mac EI 10.11.3 MySQL5.7.11 .dmg 安装(便捷设置,密码重置,卸载)
MySQL 5.7+ 安装成功以后会弹出一个临时密码 后面需要通过临时密码设置新的密码 重置root密码:安装成功后,使用临时密码登陆:敲入命令,mysqladmin -u root -p passw ...
- centos8/redhat8 无法上网,通过启动systemctl start NetworkManger搞定
在systemd里面,可以直接使用systemctl进行管理 启动:systemctl start NetworkManger 关闭:systemctl stop NetworkManager 开机启 ...
- promises的深入学习
Promise 的含义 § ⇧ Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大.它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供 ...