题意

给定 \(n\) 个路段,每个路段用三个实数 \(s_i,k_i,v^\prime_i\) 描述,最小化

\[F(v_1,\cdots v_n)=\sum\limits_{i=1}^{n}\frac{s_i}{v_i}
\]

其中 \(v_1,\cdots v_n\) 均为非负实数而且需要满足

\[\varphi(v_1,\cdots,v_n)=\sum\limits_{i=0}^{n}k_i(v_i-v^{\prime}_i)^2s_i-E_U=0
\]

\(\texttt{Data Range:}1\leq n\leq 1000\)

题解

拉格朗日乘子法。

我们来形象的讲一下这个东西到底是什么,你可能需要一些关于多元函数微积分的知识。

假设我们现在有一个二元函数 \(F(x,y)=x^2+y^2\),需要求这个东西的最小值。

如果没有限制的话,最小值就是 \(0\)。但是我如果需要让 \(x,y\) 满足 \(x^2y=3\) 的话呢?

一个很显然的想法就是去逐一枚举一个最小值 \(r\),然后看这个 \(r\) 满不满足条件。于是我们只需要看看 \(x^2y=3\) 和 \(x^2+y^2=r\) 是否相交。

注意到后者的图像是一个圆,从小到大枚举 \(r\) 的过程可以看做是圆的半径逐渐扩大。如果扩大到某个 \(r\) 刚好与 \(x^2y=3\) 相交了的话就可以取这个 \(r\) 作为最小值。

这里有一个 demo,拖动 \(r_0\) 的滑动条相当于是圆的半径逐渐扩大。注意到随着半径的扩大,圆与曲线的位置关系是先相离再相切最后相交。所以说,在极值点,圆与曲线相切

注意到这些圆是可以看做 \(F(x,y)=x^2+y^2\) 的等高线的。注意到 \(\nabla F\)(也就是梯度)是等高线的法线。同时 另一个函数 \(G(x,y)=x^2y\) 的梯度向量 \(\nabla G\) 也会垂直于 \(x^2y=3\) 这条等高线。

因为梯度向量是等高线的法线,所以梯度与等高线的切线垂直。结合两个加粗的条件我们可以知道在相切点,圆的梯度向量和曲线的梯度向量平行。这个时候我们可以列方程了:

\[\nabla F=\lambda\nabla G
\]

也就是说

\[\begin{cases}\frac{\partial F}{\partial x}=\lambda\frac{\partial G}{\partial x}\\\frac{\partial F}{\partial y}=\lambda\frac{\partial G}{\partial y}\\x^2y=3\end{cases}
\]

解出来即可。

这个时候我们可以考虑构造约束函数 \(\varphi(x,y)=x^2y-3\)。由于 \(3\) 是常数在对任何一个变量求偏导数的时候都会消去所以不会对上面两个方程产生影响。

由于偏导数的可加性,我们增加一个新的变量 \(\lambda\) 并且将原来的函数写成这样:(也就是将等式的右边移到了左边)

\[F(x,y,\lambda)=F(x,y)+\lambda\varphi(x,y)
\]

这个时候很容易看出对 \(F(x,y,\lambda)\) 求三个偏导数得到的方程与上面的方程组是一样的。

对于这个题目来说,构造函数

\[F(v_1,\cdots,v_n,\lambda)=F(v_1,\cdots,v_n)+\lambda\varphi(v_1,\cdots,v_n)=\sum\limits_{i=1}^{n}\frac{s_i}{v_i}+\lambda\left(\sum\limits_{i=0}^{n}k_i(v_i-v^{\prime}_i)^2s_i-E_U\right)
\]

根据对称性我们可以很方便的求出这个东西对 \(v_i\) 和 \(\lambda\) 的偏导数:

\[\frac{\partial F}{\partial v_i}=2\lambda k_i(v_i-v^\prime_i)s_i-\frac{s_i}{v_i^2}
\]
\[\frac{\partial F}{\partial \lambda}=\sum\limits_{i=0}^{n}k_i(v_i-v^\prime_i)^2s_i-E_U
\]

按照上面讲的东西,这些偏导数都应该等于 \(0\) 的,所以得到两个方程:

\[2\lambda k_iv_i^2(v_i-v^\prime_i)=1
\]
\[\sum k_i(v_i-v^{\prime})^2s_i=E_U
\]

将第一个方程移项得到

\[v_i^2(v_i-v^\prime_i)=\frac{1}{2\lambda k_i}
\]

左边那个东西当 \(v_i\in [0,+\infty)\) 的时候通过对导数进行分析可以看出是单调递增的。

当 \(\lambda\) 固定的时候,\(v_i\uparrow\) 则等式左边 \(\uparrow\)。当 \(\lambda\uparrow\) 时,因为等式右边 \(\downarrow\),所以 \(v_i\downarrow\)。因为 \(v_i>v^\prime_i\),所以第二个等式的左边整体是 \(\downarrow\) 的。

于是我们可以考虑二分 \(\lambda\),然后二分解出 \(v_i\) 利用第二个等式再 check 即可。

代码

#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
typedef long double db;
const ll MAXN=2e5+51;
const db eps=1e-12;
ll n;
db eu,l,r,mid,res;
db s[MAXN],kk[MAXN],v[MAXN],vl[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
#define sqr(x) (x)*(x)
inline db calcDeriv(db lambda,db vel,ll x)
{
return 2.0*lambda*kk[x]*sqr(vel)*(vel-v[x]);
}
inline ll check(db lambda)
{
db e=0,l,r,mid;
for(register int i=1;i<=n;i++)
{
l=max(v[i],0.0L),r=100000;
while(l+eps<=r)
{
mid=(l+r)/2.0;
calcDeriv(lambda,mid,i)<=1?l=mid:r=mid;
}
vl[i]=l,e+=kk[i]*sqr(vl[i]-v[i])*s[i];
}
return e<=eu;
}
int main()
{
n=read(),scanf("%Lf",&eu),l=0,r=100000;
for(register int i=1;i<=n;i++)
{
scanf("%Lf%Lf%Lf",&s[i],&kk[i],&v[i]);
}
while(l+eps<=r)
{
mid=(l+r)/2.0;
check(mid)?r=mid:l=mid;
}
for(register int i=1;i<=n;i++)
{
res+=s[i]/vl[i];
}
printf("%.9Lf\n",res);
}

Luogu P2179 [NOI2012]骑行川藏的更多相关文章

  1. 【洛谷】P2179 [NOI2012]骑行川藏

    题解 感谢小迪给我讲题啊,这题小迪写挺好的我就不写了吧 小迪的题解 代码 #include <iostream> #include <cstdio> #include < ...

  2. 洛谷P2179 [NOI2012]骑行川藏(拉格朗日乘数法)

    题面 传送门 题解 看\(mashirosky\)大佬的题解吧--这里 //minamoto #include<bits/stdc++.h> #define R register #def ...

  3. bzoj 2876: [Noi2012]骑行川藏 拉格朗日数乘

    2876: [Noi2012]骑行川藏 Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 1033  Solved: ...

  4. 2876: [Noi2012]骑行川藏 - BZOJ

    Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...

  5. bzoj2876 [Noi2012]骑行川藏

    Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...

  6. bzoj2876 [NOI2012]骑行川藏(拉格朗日乘数法)

    题目描述 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行 ...

  7. 题解 洛谷 P2179 【[NOI2012]骑行川藏】

    题意为在满足\(\sum\limits_{i=1}^nk_i(v_i-v_i^\prime)^2s_i\leqslant E_U\)的条件下最小化\(\sum\limits_{i=1}^n\frac{ ...

  8. [BZOJ2876][NOI2012]骑行川藏(拉格朗日乘数法)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2876 分析:就是要求约束条件下函数的极值,于是拉格朗日乘数列方程,发现化简后的关于vi ...

  9. 【BZOJ】2876: [Noi2012]骑行川藏

    题意 给出\(s_i, k_i, v_i', E\),满足\(\sum_{i=1}^{n} k_i s_i ( v_i - v_i' )^2 \le E, v_i > v_i'\),最小化$ \ ...

随机推荐

  1. 转载:tf.gfile的用法

    https://blog.csdn.net/a373595475/article/details/79693430

  2. Zookeeper 笔记小结

    转自: https://www.cnblogs.com/raphael5200/p/5285583.html  1.Zookeeper的角色 » 领导者(leader),负责进行投票的发起和决议,更新 ...

  3. 树莓派3B+安装64位ubuntu系统和docker工具

    想在树莓派3B上安装一些64位应用(例如64位JDK),因此首先要安装64位的操作系统,今天咱们就一起来实战: 原文地址:https://blog.csdn.net/boling_cavalry/ar ...

  4. CSS网页背景图片等比例占满整个页面的解决方案

    想做一个个人展示类的网站首页,用整张图片来当背景,浏览器窗口放大缩小时背景图片不会变形,需要用到分层来实现其他功能,就用DIV来实现了 #bodycontainer { width:100%; hei ...

  5. 内存操作【memset】【memcpy】

    void *memset(void *s, int c, unsigned long n); 将指针变量 s 所指向的前 n 字节的内存单元用一个"整数" c 替换,注意 c 是 ...

  6. 【字符串算法】AC自动机

    国庆后面两天划水,甚至想接着发出咕咕咕的叫声.咳咳咳,这些都不重要!最近学习了一下AC自动机,发现其实远没有想象中的那么难. AC自动机的来历 我知道,很多人在第一次看到这个东西的时侯是非常兴奋的.( ...

  7. 如何查找一个为NULL的MYSQL字段

    前言:在做这个题目 https://www.cnblogs.com/pipihao/p/13786304.html 因为之前 我好像没有接触过什么 为NULL字段的查询,细节不小 WHERE 字段 I ...

  8. H264裸码流I/P/B帧类型判别

    花了两天时间做了个h264裸流nal类型和frame类型检测的工具,已上传至github,有需要的自行下载. 1.NAL类型检测 nal类型检测非常容易,对照下表即可容易判断类型. 较常用nal类型包 ...

  9. JVM 第五篇:命令行 JVM 故障处理工具

    本文内容过于硬核,建议有 Java 相关经验人士阅读. 1. 引言 虽然我们前面介绍了各种图形化 JVM 故障处理工具,但是很多情况下,我们在处理问题的时候并没有图形化的操作环境可以使用,这时候,就需 ...

  10. 要是想让程序跳转到绝对地址是0x100000去执行

    要对绝对地址0x100000赋值,我们可以用 (unsigned int*)0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做? *((void (* ...