【NOI2012】骑行川藏(拉格朗日乘数法)

传送门

  • l i m i t s : φ ( v 1 , v 2 , … , v n ) = ∑ k i ( v i − v i ′ ) 2 s i = E m i n i m i z e { f ( v 1 , v 2 , … , v n ) = ∑ s i v i } L ( v 1 , v 2 , … , v n ) = f + λ φ limits:\varphi(v_1,v_2,\dots,v_n)=\sum k_i(v_i-v_i')^2s_i=E\\ minimize\{f(v_1,v_2,\dots,v_n)=\sum \frac{s_i}{v_i}\}\\ L(v_1,v_2,\dots,v_n)=f+\lambda \varphi limits:φ(v1,v2,,vn)=ki(vivi)2si=Eminimize{f(v1,v2,,vn)=visi}L(v1,v2,,vn)=f+λφ
  • l i m i t limit limit 取等是因为最优解法一定把能量用完,需要满足:
    { ∂ L ∂ v i = − s i v i 2 + 2 λ ( v i − v i ′ ) k i s i = 0 ( 1 ≤ i ≤ n ) ∑ k i ( v i − v i ′ ) s i = E \left\{ \begin{aligned} \frac{\partial L}{\partial v_i}=-\frac{s_i}{v_i^2}+2\lambda(v_i-v_i')k_is_i=0(1\le i\le n)\\ \sum k_i(v_i-v_i')s_i=E \end{aligned} \right. viL=vi2si+2λ(vivi)kisi=0(1in)ki(vivi)si=E
    那么直接二分 λ \lambda λ 就做完了
#include<bits/stdc++.h>
#define cs const
#define pb push_back
using namespace std;
cs double eps = 1e-12;
cs int N = 1e4 + 50;
int n; double E, s[N], k[N], v[N], a[N];
double sqr(double a){ return a * a; }
double clc(double v, double v0, double k){ return k*v*v*(v-v0)*2; }
double chk(double lambda){
	double sm=0;
	for(int i=1; i<=n; i++){
		double l=max(0.0,v[i]), r=1e5;
		while(r-l>eps){
			double mid=(l+r)/2;
			if(lambda*clc(mid,v[i],k[i])>=1) r=mid; else l=mid;
		} a[i]=l; sm=sm+k[i]*sqr(a[i]-v[i])*s[i];
	} return sm;
}
double work(){ double as=0; for(int i=1; i<=n; i++) as=as+s[i]/a[i]; return as; }
int main(){
	scanf("%d%lf",&n,&E);
	for(int i=1; i<=n; i++)
	scanf("%lf%lf%lf",&s[i],&k[i],&v[i]);
	double l=0, r=1e5;
	while(r-l>eps){
		double mid=(l+r)/2;
		if(chk(mid)>E) l=mid; else r=mid;
	} printf("%.8lf",work()); return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值