很好的dp
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int N=500005;
int now,n,m,p;
ll dp[2][N],f[N],d[N],sum[N];
int q[N],head,tail;
ll getup(int j,int k)
{
return (dp[now^1][j]+sum[j])-(dp[now^1][k]+sum[k]);
}
ll getdown(int j,int k) {return j-k;}
int main()
{
scanf("%d%d%d",&n,&m,&p);
for (int i=2;i<=n;i++) scanf("%I64d",&d[i]),d[i]+=d[i-1];
for (int h,i=1;i<=m;i++)
{
ll t;
scanf("%d%I64d",&h,&t);
f[i]=t-d[h];
}
sort(f+1,f+m+1);
for (int i=1;i<=m;i++) sum[i]=sum[i-1]+f[i],dp[0][i]=1e15;
ll ans=1e18;
now=1;
for (int t=1;t<=p;t++)
{
q[head=tail=1]=0;
for (int i=1;i<=m;i++)
{
while (head<tail&&getup(q[head+1],q[head])<=f[i]*getdown(q[head+1],q[head])) head++;
dp[now][i]=dp[now^1][q[head]]+(ll)(i-q[head])*f[i]-(sum[i]-sum[q[head]]);
while (head<tail&&getup(i,q[tail])*getdown(q[tail],q[tail-1])<=getup(q[tail],q[tail-1])*getdown(i,q[tail])) tail--;
q[++tail]=i;
}
ans=min(ans,dp[now][m]);
now^=1;
}
printf("%I64d",ans);
return 0;
}