[NOI2012]骑行川藏——拉格朗日乘子法
前置芝士:拉格朗日乘子法
要求\(n\)元目标函数\(f(x_1,x_2,...,x_n)\)的极值,且有\(m\)个约束函数形如\(h_i(x_1,x_2,...,x_n)=0\)
引入松弛变量\(\alpha _1-\alpha _m\),构造拉格朗日函数如下:
\]
然后分别对\(x\)和\(a\)求偏导并令偏导值为\(0\)($\nabla $为梯度向量):
\]
求解上述方程组,即可求得极值点。但是解方程组的代价太大了,在做题时我们一般会通过函数的单调性二分来解
为什么可以这样呢,考虑一下,满足条件的极值点应该是在目标函数的等高线与约束函数曲线相切的点,在这一点上有如下等式成立:
\]
而拉格朗日函数求导之后和上式本质相同,因此它能求得最值
还有广义拉格朗日乘子法是适用于有不等式约束的情况
题解
首先我们把目标函数和约束函数都找出来
目标函数$f(x)=\sum\limits_{i=1}^{n}\frac{s_i}{v_i}$
约束函数$g(x)=\sum\limits_{i=1}^{n}k_is_i(v_i-v'_i)^2-E_U$
那么拉格朗日函数为
$$L(x,\alpha)=f(x)+\alpha g(x)=-\alpha E_U+\sum\limits_{i=1}^{n}\frac{s_i}{v_i}+\alpha k_is_i(v_i-v'_i)^2$$
求出$v_i$关于$L$的偏导并将其设置为$0$
$$\frac{\partial L(v,\alpha)}{\partial v_i}=-\frac{s_i}{v_i^2}+2\alpha s_ik_i(v_i-v'_i)=0$$
$$\Rightarrow \alpha=\frac{1}{2k_iv_i^2(v_i-v'_i)}$$
经过简单讨论,可以得出$\alpha$随$v$单调递减,$g$随$v$单调递增,所以$g$随$\alpha$单调递减
于是我们可以先二分$\alpha$,然后再二分解出$v$,复杂度$O(nlog^2n)$
附代码:
```cpp
#include
using namespace std;
define N 10000
const double eps = 1e-13, INF = 1e5;
int n;
double Eu, s[N + 5], k[N + 5], v0[N + 5], v[N + 5];
bool check(double lamda) {
for (int i = 1; i <= n; ++i) {
double tar = 1 / (2 * k[i] * lamda), l = max(v0[i], 0.0), r = INF, mid;
while(r - l >= eps) {
mid = (l + r) / 2;
if (mid * mid * (mid - v0[i]) > tar) r = mid;
else l = mid;
}
v[i] = mid;
}
double E = 0;
for (int i = 1; i <= n; ++i)
E += k[i] * s[i] * pow(v[i] - v0[i], 2);
return E <= Eu;
}
int main() {
cin >> n >> Eu;
for (int i = 1; i <= n; ++i)
cin >> s[i] >> k[i] >> v0[i];
double l = 0, r = INF, mid;
while (r - l >= eps) {
mid = (l + r) / 2;
if (check(mid)) r = mid;
else l = mid;
}
double ans = 0;
for (int i = 1; i <= n; ++i)
ans += s[i] / v[i];
cout << setiosflags(ios::fixed) << setprecision(10);
cout << ans << endl;
return 0;
}
[NOI2012]骑行川藏——拉格朗日乘子法的更多相关文章
- [BZOJ2876][NOI2012]骑行川藏(拉格朗日乘数法)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2876 分析:就是要求约束条件下函数的极值,于是拉格朗日乘数列方程,发现化简后的关于vi ...
- bzoj 2876: [Noi2012]骑行川藏 拉格朗日数乘
2876: [Noi2012]骑行川藏 Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1033 Solved: ...
- bzoj2876 [Noi2012]骑行川藏
Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...
- [NOI2012] 骑行川藏 | 求导 二分
一个能看的题解!预备知识只有高中数学的[导数].不用什么偏导数/拉格朗日乘子法之类的我看不懂的东西( •̀∀•́ )! 如果你不知道什么是导数,可以找本高中数学选修2-2来看一下!看第一章第1.2节就 ...
- 【bzoj2876】 Noi2012—骑行川藏
http://www.lydsy.com/JudgeOnline/problem.php?id=2876 (题目链接) 题意 在满足约束条件$${\sum_{i=1}^ns_ik_i(v_i-v_i' ...
- Luogu P2179 [NOI2012]骑行川藏
题意 给定 \(n\) 个路段,每个路段用三个实数 \(s_i,k_i,v^\prime_i\) 描述,最小化 \[F(v_1,\cdots v_n)=\sum\limits_{i=1}^{n}\fr ...
- bzoj2876 [NOI2012]骑行川藏(拉格朗日乘数法)
题目描述 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行 ...
- 2876: [Noi2012]骑行川藏 - BZOJ
Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...
- BZOJ2876 [Noi2012]骑行川藏 【拉格朗日乘数法】
题目链接 BZOJ 题解 拉格朗日乘数法 拉格朗日乘数法用以求多元函数在约束下的极值 我们设多元函数\(f(x_1,x_2,x_3,\dots,x_n)\) 以及限制\(g(x_1,x_2,x_3,\ ...
随机推荐
- C#,CLR,IL,JIT概念 以及 .NET 家族
C#,CLR,IL,JIT概念 以及 .NET 家族 Monitor 类通过向单个线程授予对象锁来控制对对象的访问.对象锁提供限制访问代码块(通常称为临界区)的能⼒.当 ⼀个线程拥有对象的锁时,其 ...
- 35.百度云语音识别接口使用及PyAudio语音识别模块安装
百度云语音识别接口使用: 百度云语音识别接口文档:https://cloud.baidu.com/doc/SPEECH/ASR-API.html#JSON.E6.96.B9.E5.BC.8F.E4.B ...
- 前端ajax中运用post请求和get请求之于session验证
首先我们来看下ajax两种请求的区别: Ajax中POST和GET的区别Get和Post都是向服务器发送的一种请求,只是发送机制不同. 1. GET请求会将参数跟在URL后进行传递,而POST请求则是 ...
- 远程桌面teamviewer
1.同一局域网 windows:远程桌面 2.需穿过局域网 teamviewer (1)使用 http://jingyan.baidu.com/article/ff4116259af07d12e482 ...
- Docker下mysql容器开启binlog日志(保留7天)
现有需求开启用Docker容器启动的mysql数据库的binlog,以作为 日志记录 和 数据恢复,我们了解了MySQL的binlog日志的开启方式以及binlog日志的一些原理和常用操作,我们知道, ...
- Kubernetes---容器探针
⒈含义 探针是由各个节点的kubelet对容器执行的定期诊断.要执行诊断,kubelet 调用由容器实现的Handler[处理程序].有三种类型的处理程序: >ExecAction:在容器内执行 ...
- shell脚本查询某一目录的某一部分文件并且拷贝到其他目录(有则跳过没有则拷贝)
#!/bin/bash dir=`ls /root//*` for i in $dir do #basename 返回一个字符串参数的基本文件名称.(只剩下文件名除去路径名) a=`basename ...
- 系统学习机器学习之神经网络(三)--GA神经网络与小波神经网络WNN
系统学习机器学习之神经网络(三)--GA神经网络与小波神经网络WNN 2017年01月09日 09:45:26 Eason.wxd 阅读数 14135更多 分类专栏: 机器学习 1 遗传算法1.1 ...
- async/await 的引用
static async void Start() { string s = "ass"; Console.WriteLine(getMemory(s)+"Hello W ...
- 很low的四位验证码实现
<html> <head> <meta charset="utf-8"> </head> <body> <inpu ...