cf311B(斜率优化)

来源:互联网 发布:linux上svn创建项目 编辑:程序博客网 时间:2024/06/07 23:58

 

很好的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;}


 

0 0