NC50540. Cats Transport
描述
输入描述
第一行三个整数N,M,P;
第二行N-1个正整数,表示第i座山与第i-1座山之间的距离是;
接下去M行每行两个整数。
输出描述
输出一个整数表示答案。
示例1
输入:
4 6 2 1 3 5 1 0 2 1 4 9 1 10 2 10 3 12
输出:
3
C++11(clang++ 3.9) 解法, 执行用时: 252ms, 内存消耗: 4332K, 提交时间: 2020-10-20 10:35:38
#include<bits/stdc++.h> using namespace std; const int nm=101020; int n,m,p,h,t,tt,q[nm]; long long d[nm],a[nm],s[nm],f[2][nm]; double slo(int i,int j){return 1.0*(f[0][j]+s[j]-f[0][i]-s[i])/(j-i);} int main(){ scanf("%d%d%d",&n,&m,&p); for(int i=2;i<=n;i++) scanf("%lld",d+i),d[i]+=d[i-1]; for(int i=1;i<=m;i++) scanf("%d%d",&h,&t), a[i]=1ll*t-d[h]; sort(a+1,a+m+1); for(int i=1;i<=m;i++) f[0][i]=a[i]*i-(s[i]=s[i-1]+a[i]); for(int i=2;i<=p;i++){ for(int j=1,k;j<=m;j++){ if(t>=tt)t=tt; else while(t<tt&&slo(q[t],q[t+1])<a[j])t++; k=q[t],f[1][j]=f[0][k]+a[j]*(j-k)-(s[j]-s[k]); while(tt&&slo(q[tt-1],q[tt])>=slo(q[tt],j))tt--; q[++tt]=j; }memcpy(f[0],f[1],sizeof f[0]),t=tt=0; }return printf("%lld\n",f[0][m]),0; }