CF311B Cats Transport题解斜率优化
Posted chriskkk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF311B Cats Transport题解斜率优化相关的知识,希望对你有一定的参考价值。
题面:http://codeforces.com/contest/311/problem/B
Luogu题面:https://www.luogu.com.cn/problem/CF311B
斜率优化DP
我们设t[i]=小猫结束时间-从1到它所在的地点的距离和。
也就是从什么时候开始出发可以让猫不等待。
为了最优那么我们一趟绝对要让一个不等待。
把他排序,那么就是可以接到上个饲养员接走的猫 k 后,到这次刚好接到的猫 i 之间所有的猫。
有点绕。
那么dp式子就可以推出了。
f[i][j]=min(f[i][j],f[i-1][k]+t[j]*(j-k)-(s[j]-s[k]))。
去掉min。
f[i-1][k]+s[k]=t[j]*k+f[i][j]-t[j]*j+s[j]
设成y=kx+b的形式。
那么k就是t[j],x是k,y是前面那一大堆。
就可以快乐的维护下凸壳斜率优化了。
代码如下:
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1e5+10; ll f[110][maxn],g[maxn],s[maxn],t[maxn]; int n,m,p,d[maxn],q[maxn]; int main() scanf("%d%d%d",&n,&m,&p); for(int i=2;i<=n;i++) scanf("%d",&d[i]);d[i]+=d[i-1]; for(int i=1;i<=m;i++) int x,y;scanf("%d%d",&x,&y); t[i]=y-d[x]; sort(t+1,t+1+m); for(int i=1;i<=m;i++) s[i]=s[i-1]+t[i]; memset(f,0x3f,sizeof(f)); f[0][0]=0; for(int i=1;i<=p;i++) for(int j=1;j<=m;j++) g[j]=f[i-1][j]+s[j]; int l=1,r=1;q[1]=0; for(int j=1;j<=m;j++) while(l<r && g[q[l+1]]-g[q[l]]<=t[j]*(q[l+1]-q[l])) l++; f[i][j]=min(f[i-1][j],g[q[l]]+t[j]*(j-q[l])-s[j]); if(g[j]>=0x3f3f3f3f3f3f3f3fll) continue; while(l<r && (g[j]-g[q[r]])*(q[r]-q[r-1])<=(g[q[r]]-g[q[r-1]])*(j-q[r])) r--; q[++r]=j; printf("%lld\n",f[p][m]); return 0;
以上是关于CF311B Cats Transport题解斜率优化的主要内容,如果未能解决你的问题,请参考以下文章
斜率优化DP Cats Transport LibreOJ - 10187
Codeforces311 B. Cats Transport(斜率优化dp)