运输小猫
2022/3/7 23:15:37
本文主要是介绍运输小猫,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
有m个猫 p个人 n个地点 每个点有若干只猫
每个猫会在\(t_i\)的时候可以开始被接走
每个人只能从1走到n 距离上要花费时间
求小猫等待时间的和的最小值
贪心来创造dp序:
可以先考虑没有距离的情况 然后把距离减到 构成等效时间
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define ll long long using namespace std; const int N=1e5+10; const ll INF=0x3f3f3f3f3f3f3f3f; int read() { int x=0,f=0,c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return f?-x:x; } int n,m,p; ll d[N],h[N],t[N],a[N],sum[N],f[2][N]; int q[N],l,r; //(x,f[i-1][x]+sum[x]) ll Y(int i,int x){return f[i^1][x]+sum[x];}; bool cmp_b(int i,int j1,int j2,int j3) { return ( Y(i,j2)-Y(i,j1) )*(j3-j2) >= ( Y(i,j3)-Y(i,j2) )*(j2-j1); } bool cmp_f(int i,int j1,int j2,ll k) { return (Y(i,j2)-Y(i,j1)) <= k*(j2-j1); } //n个地点 m只猫 p个人 int main() { n=read(); m=read(); p=read(); for(int i=2;i<=n;i++) d[i]=d[i-1]+read(); for(int i=1;i<=m;i++) h[i]=read(),t[i]=read(); for(int i=1;i<=m;i++) a[i]=t[i]-d[h[i]]; sort(a+1,a+m+1); for(int i=1;i<=m;i++) sum[i]=sum[i-1]+a[i]; memset(f,0x3f,sizeof f);//初值还有防止赋值的作用 f[0][0]=f[1][0]=0; // i&1 -> (i&1)^1 for(int i=1;i<=p;i++) { bool now=i&1; l=r=1; q[l]=0; for(int j=1;j<=m;j++) { while(l<r&&cmp_f(now,q[l],q[l+1],a[j])) l++; f[now][j]=f[now^1][q[l]]+a[j]*(j-q[l])-(sum[j]-sum[q[l]]); while(l<r&&cmp_b(now,q[r-1],q[r],j)) r--; q[++r]=j; } } printf("%lld",f[p&1][m]); return 0; }
注意: 在i=1的初值转移的时候 取min操作要通过合理赋值 来保证只能有一个值来转移
因此通常会用到无穷大无穷小的操作
取min的时候 在边界出 只有一个值能成功转移
这篇关于运输小猫的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南