首页 > 其他分享 >P2120 [ZJOI2007] 仓库建设

P2120 [ZJOI2007] 仓库建设

时间:2024-07-13 10:08:43浏览次数:17  
标签:min 仓库 sum P2120 MAXN Func front ZJOI2007 dq

题目大意

\(n\) 个工厂,每个工厂有 \(p_i\) 的货物,货物运输一个单位距离的费用是 \(1\),工厂可以建造仓库,费用为 \(c_i\)。工厂与工厂 \(1\) 的距离为 \(x_i\)。要求将货物运送到下一个最近的仓库,求最小费用。

\(1\leq n\leq 10^6\)

思路

先考虑最基本的动规:
设 \(f_i\) 表示在这里建仓库时 \([1,i]\) 的转移与建造的最小费用。则有方程:

\[f_i=\min(f_j+\sum_{k=j+1}^i(x_i-x_k)p_k)+c_i) \]

化简:

\[f_i=\min(f_j+\sum_{k=j+1}^ix_ip_k-\sum_{k=j+1}^ix_kp_k+c_i) \]

\[f_i=\min(f_j+x_i\sum_{k=j+1}^ip_k-\sum_{k=j+1}^ix_kp_k+c_i) \]

设 \(s_x=\sum_{i=1}^x p_i\),\(v_x=\sum_{i=1}^x x_ip_i\),则原式化为:

\[f_i=\min(f_j+x_i(s_i-s_j)-(v_i-v_j)+c_i) \]

\[f_i=\min(f_j+x_is_i-x_is_j-v_i+v_j+c_i) \]

整理一下就是设函数 \(F_k(x)=-s_kx+f_k+v_k\),\(C_k=s_kx_k-v_k+c_k\) 则原式就转化成了斜率优化可以做的样子:

\[f_i=\min(F_j(x_i)+C_i) \]

对于要求的 \(f_i\),维护 \(F_k\) 其中 \(k\in[0,i)\)。之后找到一个最优的 \(F_k\) 使得 \(F_k(x_i)\) 能取到最低点。换句话说我们维护的是一个凸包。像:
image
这里的紫色部分显然就是答案。之后考虑维护。

观察到 \(s\) 严格单调递增,即 \(F_k\) 的斜率 \(-s_k\) 严格单调下降,换句话说只要当前的这个函数不够优秀那我们以后都不再会选择了。可以考虑将函数维护成单调队列。发现凸包会被交点分成一段一段,则我们只要删除的时候发现交点大于 \(x_i\) 就可以舍去。则之后的 \(f_i\) 可以设成 \(f_i=F_{\text{front}}(x_i)+C_i\),其中 \(\text{front}\) 指单调队列队首。然后考虑插入 \(F_i\)。可以直接用当前的最后一个交点与次大函数与 \(F_i\) 的交点进行比较,如果小的话就可以继续出队列,直到更新不好为止,之后插入 \(F_i\)。

求函数交点很好求。对于 \(y_0=kx+b\) 与 \(y_1=px+q\) 来说它们的交点就是

\[kx+b=px+q \]

\[kx-px=q-b \]

\[x=\frac{q-b}{k-p} \]

特别的,在插入函数时如果它们的斜率一样就可以直接取截距小的那个,因为它们平行(或重合),当然取截距小的。

代码

#include<bits/stdc++.h>
#define v(u,x) (u.a*1.0*x+u.b)
using namespace std;
typedef long long ll;
typedef long double ld;
const ll MAXN=1e6+5;
struct Func{
	ld a,b;
	Func(ld _a,ld _b){
		a=_a;
		b=_b;
	}
};
ld jd(Func p,Func q){
	if(p.a==q.a){
		if(p.b>=q.b){
			return 1e18;
		} 
		return -1e18;
	}
	return (q.b-p.b)*1.0/(p.a-q.a);
}
ll sxp[MAXN],sp[MAXN];
ll n;
ll x[MAXN],p[MAXN],c[MAXN]; 
ll f[MAXN];
deque<Func>dq;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>x[i]>>p[i]>>c[i];
		sp[i]=sp[i-1]+p[i];
		sxp[i]=sxp[i-1]+x[i]*p[i];
	}
	dq.push_back(Func(0,0));
	for(int i=1;i<=n;++i){
		while(dq.size()>1){
			Func F=dq.front();
			dq.pop_front();
			if(jd(dq.front(),F)>x[i]){
				dq.push_front(F);
				break;
			}
		}
		f[i]=v(dq.front(),x[i])+sp[i]*x[i]-sxp[i]+c[i];
		Func nw=Func(-sp[i],f[i]+sxp[i]);
		while(dq.size()>1){
			Func F=dq.back();
			dq.pop_back();
			if(jd(dq.back(),F)<jd(dq.back(),nw)){
				dq.push_back(F);
				break;
			}
		}
		dq.push_back(nw);
	}
	ll ans=1e18;
	for(int i=n;i>=1;--i){
		ans=min(ans,f[i]);
		if(p[i]){
			cout<<ans<<endl;
			return 0;
		}
	}
	return 0;
} 

标签:min,仓库,sum,P2120,MAXN,Func,front,ZJOI2007,dq
From: https://www.cnblogs.com/tanghg/p/18299711/solution-p2120

相关文章

  • centos7 镜像仓库都失效了,怎么办?
    1、centos7镜像仓库都失效了,怎么办?背景:我刚才使用yum命令安装软件是,失败了。错误信息如下: 很明显,就是http://mirrorlist.centos.org无法访问到,出现了404。原因:CentOSLinux7的生命周期(EOL)于2024年6月30日终止。了解红帽帮助您轻松迁移的选项,包括支持第三方Linux......
  • git切换远程仓库地址
    git更换远程仓库地址三种方法总结一、前言由于之前项目管理使用私服的gitlab,现在换成了Gitea,需要修改远端仓库地址。二、环境windows10gitversion2.34.0.windows.1三、帮助文档GitHub文档四、三种修改方法方法一:不删除远程仓库修改(最方便)#查看远端地址git......
  • 编译安装Kubernetes 1.29 高可用集群(9)--Harbor私有仓库部署
    1.环境说明操作系统:openEuler22.03软件版本:harbor2.10.32.Harbor软件安装2.1安装前准备#systemctldisablefirewalld.service#systemctlstopfirewalld.service#sed-i's/SELINUX=enforcing/SELINUX=disabled/'/etc/selinux/config#setenforce0#hostnamec......
  • 实战Qt开发WordBN笔记软件#02 通过Gitee创建YourWordBN仓库;学会GIT常用指令,并实现多分
    01背景【WordBN字远笔记】是天恩软件工作室开发的一款免费笔记软件;WordBN基于VS2019、Qt6.5开发,使用QtQuick(QML)开发语言。本课程将以【WordBN字远笔记】的界面为实战基础,详细介绍如何基于Qt/QML开发语言,从零开始开发一套真正的程序,包括国际化、版本发布、安装包制作等项目......
  • 阿里云镜像仓库的使用详解
    一、镜像仓库介绍Registry是Docker公司的一项创新,它提供了存放镜像的仓库服务。在构建好镜像后,我们通常会将镜像上传到Registry服务器上进行保存。这样可以保证不会因本机故障而导致镜像丢失,同时,其他机器也能很方便地通过网络方式下载。DockerHub即为Docker官方的Registry服务......
  • 仓库管理系统
    使用方法:1.输入,借用人姓名,借用物品信息,批准人姓名2.点击借用,实现借用,信息会保存在excel文件中3.点击未归还人员,会列出未归还人员4点击未归还人员的名字5.点击归还,会归还6.借用时间和归还时间会记录。importpandasaspdfromdatetimeimportdatetimeimportPy......
  • 深入解析大数据核心概念:数据平台、数据中台、数据湖与数据仓库的异同与应用
    大数据领域内的诸多概念常常让人困惑,其中数据平台、数据中台、数据湖和数据仓库是最为关键的几个。1.数据平台定义:数据平台是一个综合性的技术框架,旨在支持整个数据生命周期的管理和使用。它包含数据采集、存储、处理、分析和可视化等多个环节。特点:全流程支持:从数据的......
  • 把本地已经创建的项目推送到gitee上新创建的同名仓库
    1.在gitee上新建项目demo-programe创建后,如下:2.在本地创建同名项目文件2.1.进入文件夹2.2.在文件夹里面,初始化文件夹(gitinit)gitinit2.3.把.gitignore文件加入文件夹中2.4..gitignore文件内容如下3.把本地demo-programe文件夹推送到gitee新建的demo-programe......
  • 智慧仓库:EasyCVR视频监控汇聚+AI视频分析技术在仓库安全管理中的应用
    随着科技的飞速发展,物流行业正迎来前所未有的变革。智慧仓库作为物流领域的重要组成部分,以其高效、智能、自动化的特点,成为推动行业升级的关键,特别是在智慧仓库的管理中,视频监控技术发挥着举足轻重的作用。一、视频监控技术在智慧仓库中的基础应用在智慧仓库中,视频汇聚EasyCVR安......
  • git 如何 fork 一个仓库的所有分支
    假设要fork的仓库名称为a,你的本地仓库名称为b克隆a仓库的[email protected]:username/a.gitcda添加b仓库为上游(upstream)远程仓库[email protected]:username/b.git获取所有分支gitfetchupstream查看所有分支gitbranch......