首页 > 其他分享 >斜率优化解题报告(uoj转)

斜率优化解题报告(uoj转)

时间:2024-09-27 09:01:58浏览次数:1  
标签:min cdot tt Sp 斜率 解题 SC uoj sum

任务安排1~3:

模版。用到一个著名的思想:费用提前计算

暴力维数高的原因是不能较快的知道前面分了几批

但是一旦分了一批,对后面都会有\(S\)的时间叠加

所以不妨设\(f_i\)表示已知会花费的时间min,

\(f_i = \min_{j=1}^{i-1} f_j + (SC_i-SC_j) \cdot ST_i + S \cdot (SC_n-SC_j)\)

\(O(n^2)\)通过T1.

大力拆式子,发现有一个叫做\(ST_i \cdot SC_j\)的玩意,i,j之间无法独立

不慌,还是先移项,得

\(f_j-SC_j \cdot S = ST_i \cdot SC_j + f_i - ST_i \cdot SC_i - S \cdot SC_n\)

\(i\)为常数,\(j\)为变量的话此为一次函数,维护下凸包即可

关于为何是下凸包:

1.直观理解:下面的截距才小,\(f_i\)才小

2.线性规划的结论证明

3.分类讨论证明

能理解就行

这样2、3都秒了,只是在单调队列中取哪个做答案的问题

其实还可以有4,\(T_i\)也能是负数

在凸包中间插点,set维护即可


B. Cats Transport

乍一看很难搞,两三个属性

分析一波,若feeder(\(t\)时刻出发)接到了一只cute cat,则它应该等待\(t+SD_i-T_i\)分钟(\(t \geq T_i -SD_i\))

所以可设\(a_i = T_i - SD_i\)并排序

不难发现\(a\)小的cat应由出发早的人接

人少,可设\(f_{i,j}\)表示前\(i\)个人接走前\(j\)个cat最小时间

\(f_{i,j}=f_{i-1,k}+(j-k)*Sa_j-(Sa_j-Sa_k)\)

(贪心设置的t,无需多言)

\(i\)直接滚掉,移项得

\(pre_j + Sa_j = j \cdot Sa_i + f_i + (i-1) \cdot Sa_i\)

结束战斗


P3195 [HNOI2008]玩具装箱

套路了。。。

\(f_i\)表示前\(i\)个分好最小代价

设\(s_i = \sum_{j=1}^i c_j\)

\(f_i = f_j + (s_i-s_j+i-j-1-L)^2\)

设\(a_i=s_i+i\) , \(R = 1 - L\) , 则

\(f_i = f_j + (a_i - a_j + R)^2\),

化简即可不想写了

#include<bits/stdc++.h>
using namespace std;
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define N 100005
#define ll long long
int n,q[N],hh,tt;
ll f[N],s[N],D;
ll get_y(int j){
	return f[j]+(s[j]-D)*(s[j]-D);
}
int main(){
	scanf("%d%lld",&n,&D);
	D=-1ll-D;
	fr(i,1,n){
		scanf("%lld",&s[i]);
		s[i]+=s[i-1]; 
	}
	fr(i,1,n)s[i]+=1ll*i;
	fr(i,1,n){
		while(hh<tt&&(get_y(q[hh+1])-get_y(q[hh]))<2ll*s[i]*(s[q[hh+1]]-s[q[hh]]))hh++;
		f[i]=f[q[hh]]+1ll*(s[i]-s[q[hh]]+D)*(s[i]-s[q[hh]]+D); 
		while(hh<tt&&(get_y(q[tt])-get_y(q[tt-1]))*(s[i]-s[q[tt]])>=(get_y(i)-get_y(q[tt]))*(s[q[tt]]-s[q[tt-1]]))tt--;
		q[++tt]=i;
	}
	printf("%lld\n",f[n]);
	return 0;
}

P2120 [ZJOI2007]仓库建设

\(f_i\)表示前\(i\)个的min

\(f_i = \min_{j=1}^{i-1} (f_j + c_i + x_i \cdot (Sp_i - Sp_j) - (Sxp_i - Sxp_j))\)

tips:其实不需要把整个式子拆开,只需观察出\(x\),\(y\),\(Slope\)即可

还是很好找的

注意此时钦定了\(n\)号位必建仓库,特判即可

#include<bits/stdc++.h>
using namespace std;
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define N 1000005
#define ll __int128
int n,q[N],hh,tt;
ll f[N],x[N],c[N],Sp[N],Sxp[N];
ll get_y(int j){
	return f[j]+Sxp[j];
}
int main(){
	scanf("%d",&n);
	int tmp,tmp1,tmp2,fl=0;
	fr(i,1,n){
		scanf("%d%d%d",&tmp1,&tmp,&tmp2);
		x[i]=tmp1,c[i]=tmp2;
		Sp[i]=Sp[i-1]+tmp;
		Sxp[i]=Sxp[i-1]+x[i]*tmp;
		if(i==n&&tmp==0)fl=1;
	}
	fr(i,1,n){
		while(hh<tt&&(get_y(q[hh+1])-get_y(q[hh]))<(Sp[q[hh+1]]-Sp[q[hh]])*x[i])hh++;
		f[i]=f[q[hh]]+c[i]+x[i]*(Sp[i]-Sp[q[hh]])-(Sxp[i]-Sxp[q[hh]]);
		while(hh<tt&&(get_y(q[tt])-get_y(q[tt-1]))*(Sp[i]-Sp[q[tt]])>=(get_y(i)-get_y(q[tt]))*(Sp[q[tt]]-Sp[q[tt-1]]))tt--;
		q[++tt]=i;
	}
	printf("%lld\n",(long long)f[n]-fl*c[n]);
	return 0;
}

P3628 [APIO2010]特别行动队

一时竟分不清哪个是模版

\(f_i = f_j + A(s_i - s_j)^2+B(s_i-s_j) + C\)

《不难看出》,
\(y = f_j + As_j^2-Bs_j\) ,
\(x = s_j\) , \(Slope = 2As_i\)

舒服~

#include<bits/stdc++.h>
using namespace std;
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define N 1000005
#define ll long long
int n,q[N],hh,tt;
ll s[N],f[N],A,B,C;
ll get_y(int j){
	return f[j]+A*s[j]*s[j]-B*s[j];
}
int main(){
	scanf("%d%lld%lld%lld",&n,&A,&B,&C);
	ll x;
	fr(i,1,n){
		scanf("%lld",&x);
		s[i]=s[i-1]+x;
	}
	fr(i,1,n){
		while(hh<tt&&get_y(q[hh+1])-get_y(q[hh])>(s[q[hh+1]]-s[q[hh]])*2ll*A*s[i])hh++;
		int j=q[hh];
		f[i]=f[j]+A*(s[i]-s[j])*(s[i]-s[j])+B*(s[i]-s[j])+C;
		while(hh<tt&&(get_y(q[tt])-get_y(q[tt-1]))*(s[i]-s[q[tt]])<=(get_y(i)-get_y(q[tt]))*(s[q[tt]]-s[q[tt-1]]))tt--;
		q[++tt]=i;
	}
	printf("%lld\n",f[n]);
	return 0;
}

P4360 [CEOI2004]锯木厂选址

可以看出考虑\(f_i\)表示\(i\)处已经有一个兜底,还能再建一个,运完前\(i\)个最小代价

则\(f_i\)

\(= \min_{j=1}^{i-1}(\sum_{k=1}^j(x_j-x_k) \cdot p_k+\sum_{k=j+1}^i(x_i-x_k) \cdot p_k)\)

\(= x_j\sum_{k=1}^j p_k+x_i\sum_{k=j+1}^i p_k -\sum_{k=1}^i x_k \cdot p_k\)

\(= x_j \cdot Sp_j + x_i \cdot Sp_i - x_i \cdot Sp_j - Sxp_i\)

整理得

\(x_j \cdot Sp_j = x_i \cdot Sp_j + f_i - x_i \cdot Sp_i + Sxp_i\)

没有\(f_j\)好害怕

一样嘛,就是把只有\(j\)的全移到左边当\(y\),\(ij\)乘积项当\(x\),其余截距,这是精髓

求出\(f_i\),\(ans = \min_{i=1}^n (f_i + \sum_{j=i+1}^n(x_{n+1}-x_j) \cdot p_j)\)

小发现:\(\sum x \cdot p\)可以最后一起算

#include<bits/stdc++.h>
using namespace std;
#define fr(i,a,b) for(int i=a;i<=b;i++)
#define N 20005
#define ll long long
int n,q[N],hh,tt;
ll ans=1e18,f[N],x[N],p[N],res;
ll get_y(int j){
	return x[j]*p[j];
}
int main(){
	scanf("%d",&n);
	ll tmp;
	fr(i,1,n){
		scanf("%lld%lld",&p[i],&tmp);
		res+=x[i]*p[i];
		p[i]+=p[i-1];
		x[i+1]=x[i]+tmp;
	}
	fr(i,1,n){
		while(hh<tt&&get_y(q[hh+1])-get_y(q[hh])<(p[q[hh+1]]-p[q[hh]])*x[i])hh++;
		f[i]=x[i]*p[i]+p[q[hh]]*(x[q[hh]]-x[i]);
		while(hh<tt&&(get_y(q[tt])-get_y(q[tt-1]))*(p[i]-p[q[tt]])>(get_y(i)-get_y(q[tt]))*(p[q[tt]]-p[q[tt-1]]))tt--;
		q[++tt]=i;
		ans=min(ans,f[i]+x[n+1]*(p[n]-p[i]));
	}
	printf("%lld\n",ans-res);
	return 0;
}

完结撒电脑

标签:min,cdot,tt,Sp,斜率,解题,SC,uoj,sum
From: https://www.cnblogs.com/zsj6315/p/18434959

相关文章

  • 单调队列优化DP解题报告(uoj转)
    Fence\(K\)很小,考虑\(K\)开一维,\(N\)开一维\(f_{i,j}\)表示前\(i\)个工匠粉刷前\(j\)个木板的最大花费\(f_{i,j}=\min_{k=j-l_i}^{s_i-1}f_{i-1,k}+(j-k)\cdotp_i\)拆开为\(f_{i,j}=f_{i-1,k}-k\cdotp_i+j\cdotp_i\)\(i\)固定时维护\(f_{i-1,k}-k\cdotp_i\)的最小......
  • log型数据结构优化DP解题报告(uoj)
    交作业用T220417最长公共上升子序列不难看出状态同最长公共子序列,但由于上升条件限制,加一个限制:\(f_{i,j}\)表示\(a_{1...i}\)匹配\(b_{1...j}\)且\(a_i\)必须做结尾的最长公共上升子序列长度转移方程为\(f_{i,j}=f_{i,j-1}\)(if\(a_i\neqb_j\))\(f_{i,j}=\max_{k......
  • CF套题4翻译(uoj转载)
    \(A\)题:CF1098A给你一棵树,树根为\(1\)号点。每个点\(i\)有一个非负整数权值\(a_i\),记点\(i\)到根的路径上经过的所有点(包括根和自身)的权值总和为\(s_i\)。现在擦去所有深度为偶数的点的\(s_i\),求\(\suma_i\)最小可能是多少,如果无解,输出\(-1\)。被擦去的\(s_i\)在输入文件中被......
  • 专业学习|动态规划(概念、模型特征、解题步骤及例题)
    一、引言(一)从斐波那契数列引入自底向上算法(1)知识讲解(2)matlap实现递归(3)带有备忘录的遗传算法(4)matlap实现带有备忘录的递归算法“;”是为了不显示中间的计算结果;“==”双等号表示判断;“tic、toc”运算开始和结束的时间;(5)采用自低向上的算法进行求解和代码实现(二......
  • 2024年中国研究生数学建模竞赛C题——解题思路
    2024年中国研究生数学建模竞赛C题——解题思路数据驱动下磁性元件的磁芯损耗建模——解决思路二、问题描述为解决磁性元件磁芯材料损耗精确计算问题,通过实测磁性元件在给定工况(不同温度、频率、磁通密度)下磁芯材料损耗的数据,通过数学建模(或算法)方法,建立功率磁性元件的磁芯材料损耗......
  • Java解题:求商和余数
    题目:给定两个整数,被除数和除数(都是正数,且不超过int的范围)要求不使用乘法、除法和%运算符,得到商和余数。题目分析我们知道,除法的本质其实就是被除数对除数不断地进行减法运算。所以,我们只需要循环这个运算,同时记录循环了多少次,就可以得到商。而最终若不够减,那么此时的被除数即是......
  • 9.20 斜率优化复习
    看我之前写的狗屎:https://www.becoder.com.cn/article/11836。当时根本就不懂斜率优化是什么。今天真的懂了,来写总结。1问题转化对于一类dp方程式:\(f(i)=\min\{f(j)+A(j)*g(i)+B(j)+t(i)\}\)。可以用斜率优化。设\(b=f(i)-t(i)\)。把当前dp转移当成是一条斜率......
  • QDUOJ手动部署心得
    手动QDUOJ部署[更推荐官网一键部署,手动有失败率,但是能更深入理解部署过程]目录★标记的部分很重要一、需求环境Docker,Docker-compose,python=3.8[推荐]#查看版本docker-vdocker-compose-v环境配置[Ubuntu20.04,不推荐22原因:前端很多前置包22不支持]:#1.docker安装#......
  • 南沙信奥老师解题:1167:再求f(x,n)
    ​ 用递归函数求解。【输入】第一数是x的值,第二个数是n的值。【输出】函数值。【输入样例】12【输出样例】0.40#include<iostream>#include<stdlib.h>usingnamespacestd;doublef(doublex,doublen){ if(n==1) returnx/(1+x); else return......
  • PMP--一模--解题--101-110
    文章目录11.风险管理--过程--识别风险→实施定性风险分析→实施定量风险分析→规划风险应对→实施风险应对→监督风险101、[单选]在项目即将进入收尾阶段时,项目经理发现了一项原来没有考虑到的新风险。该风险一旦发生,可能给最终的可交付成果带来重要影响,甚至可能使其不......