Luogu P2179 [NOI2012]骑行川藏
题意
给定 \(n\) 个路段,每个路段用三个实数 \(s_i,k_i,v^\prime_i\) 描述,最小化
\]
其中 \(v_1,\cdots v_n\) 均为非负实数而且需要满足
\]
\(\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\) 这条等高线。
因为梯度向量是等高线的法线,所以梯度与等高线的切线垂直。结合两个加粗的条件我们可以知道在相切点,圆的梯度向量和曲线的梯度向量平行。这个时候我们可以列方程了:
\]
也就是说
\]
解出来即可。
这个时候我们可以考虑构造约束函数 \(\varphi(x,y)=x^2y-3\)。由于 \(3\) 是常数在对任何一个变量求偏导数的时候都会消去所以不会对上面两个方程产生影响。
由于偏导数的可加性,我们增加一个新的变量 \(\lambda\) 并且将原来的函数写成这样:(也就是将等式的右边移到了左边)
\]
这个时候很容易看出对 \(F(x,y,\lambda)\) 求三个偏导数得到的方程与上面的方程组是一样的。
对于这个题目来说,构造函数
\]
根据对称性我们可以很方便的求出这个东西对 \(v_i\) 和 \(\lambda\) 的偏导数:
\]
\]
按照上面讲的东西,这些偏导数都应该等于 \(0\) 的,所以得到两个方程:
\]
\]
将第一个方程移项得到
\]
左边那个东西当 \(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]骑行川藏的更多相关文章
- 【洛谷】P2179 [NOI2012]骑行川藏
		题解 感谢小迪给我讲题啊,这题小迪写挺好的我就不写了吧 小迪的题解 代码 #include <iostream> #include <cstdio> #include < ... 
- 洛谷P2179 [NOI2012]骑行川藏(拉格朗日乘数法)
		题面 传送门 题解 看\(mashirosky\)大佬的题解吧--这里 //minamoto #include<bits/stdc++.h> #define R register #def ... 
- bzoj 2876: [Noi2012]骑行川藏 拉格朗日数乘
		2876: [Noi2012]骑行川藏 Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1033 Solved: ... 
- 2876: [Noi2012]骑行川藏 - BZOJ
		Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ... 
- bzoj2876 [Noi2012]骑行川藏
		Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ... 
- bzoj2876 [NOI2012]骑行川藏(拉格朗日乘数法)
		题目描述 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行 ... 
- 题解 洛谷 P2179 【[NOI2012]骑行川藏】
		题意为在满足\(\sum\limits_{i=1}^nk_i(v_i-v_i^\prime)^2s_i\leqslant E_U\)的条件下最小化\(\sum\limits_{i=1}^n\frac{ ... 
- [BZOJ2876][NOI2012]骑行川藏(拉格朗日乘数法)
		题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2876 分析:就是要求约束条件下函数的极值,于是拉格朗日乘数列方程,发现化简后的关于vi ... 
- 【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'\),最小化$ \ ... 
随机推荐
- java 常用类-StringBuffer-StringBuilder
			二.StringBuffer类&StringBuilder类 2.1 简介 java.lang.StringBuffer.StringBuilder代表可变的字符序列,可以对字符 串内容进行增 ... 
- YOLOv4: Darknet 如何于 Ubuntu 编译,及使用 Python 接口
			本文将介绍 YOLOv4 官方 Darknet 实现,如何于 Ubuntu 18.04 编译,及使用 Python 接口. 主要内容有: 准备基础环境: Nvidia Driver, CUDA, cu ... 
- 你来讲讲AQS是什么吧?都是怎么用的?
			前言 在Java面试的时候,多线程相关的知识是躲不掉的,肯定会被问.我就被问到了AQS的知识,就直接了当的问,AQS知道是什么吧,来讲讲它是怎么实现的,以及哪些地方用到了它.当时自己确实没有讲好,所以 ... 
- mysql-5-aggregation
			#2.分组函数 /* 分组函数/聚合函数:传入一组值,经过统计处理,得到一个输出值 sum, avg, max, min, count */ USE myemployees; #简单使用 SELECT ... 
- Python练习题 002:奖金计算
			[Python练习题 002]企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可可提成 ... 
- What number should I guess next ?——由《鹰蛋》一题引发的思考
			What number should I guess next ? 这篇文章的灵感来源于最近技术部的团建与著名的DP优化<鹰蛋>.记得在一个月前,查到鹰蛋的题解前,我在与同学讨论时,一直试 ... 
- 078 01 Android 零基础入门  02 Java面向对象 01 Java面向对象基础 01 初识面向对象 03 创建类
			078 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 03 创建类 本文知识点:创建类 说明:因为时间紧张,本人写博客过程中只是对知识点的关 ... 
- python自动化实现验证码登录过程
			(自动化实现验证码登录,这里内容是入坑后,整合了几个文档的内容)|以下模块是使用时需要用到的首先:安装pillow库,它的作用是对图片进行简单的处理,在pytharm中使用pip install pi ... 
- SpringBoot-06-模板引擎Thymeleaf
			6. 模板引擎 Thymeleaf Thyme leaf 英译为 百里香的叶子. 模板引擎  以前开发中使用的jsp就是一个模板引擎,但是springboot 以jar的方式,并且使用嵌入式的tom ... 
- Spring的BeanFactory是什么?
			什么是BeanFactory? 提到Spring,总是让人第一时间想起IOC容器,而IOC容器的顶层核心接口就是我们的BeanFactory,如果能够理解BeanFactory的体系结构想必能让我们对 ... 
