hdu3507 Print Article

本文介绍了一种动态规划中的优化技巧,通过使用单调队列来减少DP状态的转移次数,实现高效的DP求解。文章详细解释了如何将DP状态转化为平面坐标点,利用斜率比较来确定最优转移路径,最终实现DP问题的高效解决。

传送门
s [ i ] = ∑ i = 1 n C [ i ] s[i]=\sum_{i=1}^{n}C[i] s[i]=i=1nC[i]
D P DP DP转移方程:
f [ i ] = m i n { f [ p ] + ( s [ i ] − s [ p ] ) 2 + m }         ( p ∈ [ 0 , i − 1 ] ) ) f[i]=min\{f[p]+(s[i]-s[p])^2+m\}\ \ \ \ \ \ \ (p∈[0,i-1])) f[i]=min{f[p]+(s[i]s[p])2+m}       (p[0,i1]))

0 &lt; = j &lt; k &lt; = i − 1 0&lt;=j&lt;k&lt;=i-1 0<=j<k<=i1。那么如果 j j j的转移比 k k k更优,那么有:
f [ j ] + ( s [ i ] − s [ j ] ) 2 + m &lt; f [ k ] + ( s [ i ] − s [ k ] ) 2 + m f[j]+(s[i]-s[j])^2+m&lt;f[k]+(s[i]-s[k])^2+m f[j]+(s[i]s[j])2+m<f[k]+(s[i]s[k])2+m

f [ j ] + s [ i ] 2 + s [ j ] 2 − 2 ∗ s [ i ] ∗ s [ j ] &lt; f [ k ] + s [ i ] 2 + s [ k ] 2 − 2 ∗ s [ i ] ∗ s [ k ] f[j]+s[i]^2+s[j]^2-2*s[i]*s[j]&lt;f[k]+s[i]^2+s[k]^2-2*s[i]*s[k] f[j]+s[i]2+s[j]22s[i]s[j]<f[k]+s[i]2+s[k]22s[i]s[k]

然后把只与 j j j有关的挪到一块,把只与 k k k有关的挪到一块。
( f [ j ] + s [ j ] 2 ) − ( f [ k ] + s [ k ] 2 ) &lt; 2 ∗ s [ i ] ∗ ( s [ j ] − s [ k ] ) (f[j]+s[j]^2)-(f[k]+s[k]^2)&lt;2*s[i]*(s[j]-s[k]) (f[j]+s[j]2)(f[k]+s[k]2)<2s[i](s[j]s[k])
T [ i ] = f [ i ] + s [ i ] 2 T[i]=f[i]+s[i]^2 T[i]=f[i]+s[i]2,于是有

T [ j ] − T [ k ] &lt; 2 ∗ s [ i ] ∗ ( s [ j ] − s [ k ] ) T[j]-T[k]&lt;2*s[i]*(s[j]-s[k]) T[j]T[k]<2s[i](s[j]s[k])

由于 j &lt; k j&lt;k j<k,于是 s [ j ] − s [ k ] &lt; 0 s[j]-s[k]&lt;0 s[j]s[k]<0,那么有:
T [ j ] − T [ k ] s [ j ] − s [ k ] &gt; 2 ∗ s [ i ] \frac{T[j]-T[k]}{s[j]-s[k]}&gt;2*s[i] s[j]s[k]T[j]T[k]>2s[i]

这便是从 j j j转移比从 k k k转移更优的条件。
观察发现,左边的东西可以看做是斜率。 ( k = Δ y Δ x ) (k=\frac{\Delta y}{\Delta x}) (k=ΔxΔy)
那么我们把每一个状态看做是一个点。第 i i i个状态的坐标就是 ( s [ i ] , T [ i ] ) (s[i],T[i]) (s[i],T[i])
f [ i ] f[i] f[i]时,考虑从前 i i i个点中最优的一个转移(包含坐标原点,即所有东西挤在一行)
令这个点为 j j j。考虑任意一个 k k k,满足 k &gt; j k&gt;j k>j
如果 j k jk jk这条直线斜率比 2 ∗ s [ i ] 2*s[i] 2s[i]小,那么 k k k就比 j j j更优。这是不行的。
在这里插入图片描述
所以可以想象前面的 i i i个状态在平面上对应出来一些点,一个斜率为 2 ∗ s [ i ] 2*s[i] 2s[i]的直线从下面无穷远处向上平移,它遇见的第一个点就是 f [ i ] f[i] f[i]的最优转移。
显然,该直线遇见的第一个点一定在凸包上。可以用一个队列存储这些点。
然后有一个特点,就是 s [ i ] s[i] s[i]是随着 i i i增大而增大的。
也就是说,判断所用直线的斜率是单增的。
于是队列的左边界是单增的。
注意,队列里面存的是编号。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5e5+10;
int head,tail,n,m,q[maxn];ll f[maxn],s[maxn];
inline int read(){
	int x=0;char ch=getchar();
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return x;
}
inline ll calc(int i){return f[i]+s[i]*s[i];}
inline ll getx(int i,int j){return s[i]-s[j];}
inline ll gety(int i,int j){return calc(i)-calc(j);}
int main(){
	while(scanf("%d%d",&n,&m)!=EOF){
		head=tail=0;
		for(int i=1;i<=n;++i){
			s[i]=read()+s[i-1];
			while(head<tail&&gety(q[head+1],q[head])<=2*s[i]*getx(q[head+1],q[head])) head++;
			f[i]=f[q[head]]+(s[i]-s[q[head]])*(s[i]-s[q[head]])+m;
			while(head<tail&&((calc(i)-calc(q[tail]))*(s[q[tail]]-s[q[tail-1]])<=(calc(q[tail])-calc(q[tail-1]))*(s[i]-s[q[tail]]))) tail--;
			q[++tail]=i;
		}printf("%lld\n",f[n]);
	}
}
(Kriging_NSGA2)克里金模型结合多目标遗传算法求最优因变量及对应的最佳自变量组合研究(Matlab代码实现)内容概要:本文介绍了克里金模型(Kriging)与多目标遗传算法NSGA-II相结合的方法,用于求解最优因变量及其对应的最佳自变量组合,并提供了完整的Matlab代码实现。该方法首先利用克里金模型构建高精度的代理模型,逼近复杂的非线性系统响应,减少计算成本;随后结合NSGA-II算法进行多目标优化,搜索帕累托前沿解集,从而获得多个最优折衷方案。文中详细阐述了代理模型构建、算法集成流程及参数设置,适用于工程设计、参数反演等复杂优化问题。此外,文档还展示了该方法在SCI一区论文中的复现应用,体现了其科学性与实用性。; 适合人群:具备一定Matlab编程基础,熟悉优化算法和数值建模的研究生、科研人员及工程技术人员,尤其适合从事仿真优化、实验设计、代理模型研究的相关领域工作者。; 使用场景及目标:①解决高计算成本的多目标优化问题,通过代理模型降低仿真次数;②在无法解析求导或函数高度非线性的情况下寻找最优变量组合;③复现SCI高水平论文中的优化方法,提升科研可信度与效率;④应用于工程设计、能源系统调度、智能制造等需参数优化的实际场景。; 阅读建议:建议读者结合提供的Matlab代码逐段理解算法实现过程,重点关注克里金模型的构建步骤与NSGA-II的集成方式,建议自行调整测试函数或实际案例验证算法性能,并配合YALMIP等工具包扩展优化求解能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值