E55 斜率优化DP Cats Transport
视频链接:465 斜率优化DP Cats Transport_哔哩哔哩_bilibili
#include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int N=100010,M=100010,P=110; int n,m,p,H,q[M]; LL d[N],t[N],a[N],s[N],f[P][M]; double slope(int i,int j,int k){ return 1.0*(f[i-1][j]+s[j]-f[i-1][k]-s[k]) /(j==k?1e-9:j-k); } 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%lld",&H,&t[i]), a[i]=t[i]-d[H]; sort(a+1,a+m+1); for(int i=1; i<=m; i++) s[i]=s[i-1]+a[i]; for(int i=1; i<=m; i++) f[0][i]=1e18; //非法状态的初值 for(int i=1; i<=p; i++){ //枚举人 int h=1,t=0; for(int j=1; j<=m; j++){ //枚举猫 while(h<t && slope(i,j-1,q[t])<=slope(i,q[t],q[t-1])) t--; q[++t]=j-1; while(h<t && slope(i,q[h+1],q[h])<=a[j]) h++; int k=q[h]; f[i][j]=f[i-1][k]+a[j]*(j-k)-(s[j]-s[k]); // printf("f[%d %d]=f[%d %d]+%d=%d\n",i,j,i-1,k,a[j]*(j-k)-(s[j]-s[k]),f[i][j]); } } printf("%lld\n",f[p][m]); }
#include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int N=100010,M=100010,P=110; int n,m,p,H,q[M]; LL d[N],t[N],a[N],s[N]; LL f[P][M]; LL dy(int i,int j,int k){return f[i-1][j]+s[j]-(f[i-1][k]+s[k]);} LL dx(int j,int k){return j-k;} 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%lld",&H,&t[i]), a[i]=t[i]-d[H]; sort(a+1,a+m+1); for(int i=1; i<=m; i++) s[i]=s[i-1]+a[i]; memset(f,0x3f,sizeof f); for(int i=0;i<=p;i++) f[i][0]=0; for(int i=1; i<=p; i++){ //枚举人 int h=1,t=0; for(int j=1; j<=m; j++){ //枚举猫 while(h<t && dy(i,j-1,q[t])*dx(q[t],q[t-1]) <=dx(j-1,q[t])*dy(i,q[t],q[t-1])) t--; q[++t]=j-1; while(h<t && dy(i,q[h+1],q[h]) <=dx(q[h+1],q[h])*a[j]) h++; int k=q[h]; f[i][j]=f[i-1][k]+a[j]*(j-k)-(s[j]-s[k]); } } printf("%lld\n",f[p][m]); }
练习:
Luogu P2900 [USACO08MAR]Land Acquisition G