首页 > 其他分享 >「NOI2012」骑行川藏

「NOI2012」骑行川藏

时间:2023-05-22 19:34:37浏览次数:48  
标签:le frac double sum NOI2012 text 川藏 骑行 lambda

题目

点这里看题目。


题目描述

蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨。

川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行前设定好目的地,同时合理分配好自己的体力是一件非常重要的事情。

由于蛋蛋装备了一辆非常好的自行车,因此在骑行过程中可以认为他仅在克服风阻做功(不受自行车本身摩擦力以及自行车与地面的摩擦力影响)。

某一天他打算骑 \(n\) 段路,每一段内的路况可视为相同:对于第 \(i\) 段路,我们给出有关这段路况的 \(3\) 个参数 \(s_i,k_i,v_i'\),其中 \(s_i\) 表示这段路的长度,\(k_i\) 表示这段路的风阻系数,\(v_i'\) 表示这段路上的风速(\(v_i'\gt 0\) 表示在这段路上他遇到了顺风,反之则意味着他将受逆风影响)。

若某一时刻在这段路上骑车速度为 \(v\),则他受到的风阻大小为 \(F=k_i(v-v_i')^2\)(这样若在长度为 \(s\) 的路程内保持骑行速度 \(v\) 不变,则他消耗能量(做功)\(E=k_i(v-v_i')^2s\) )。

设蛋蛋在这天开始时的体能值是 \(E_U\),请帮助他设计一种行车方案,使他在有限的体力内用最短的时间到达目的地。请告诉他最短的时间 \(T\) 是多少。

数据规模与约定

所有数据满足 \(1\le n\le 10^4,E_U\le 10^8,s_i\in (0,10^5],k_i\in (0,15],v_i'\in (-100,100)\)。

提示

必然存在一种最优的体力方案满足:蛋蛋在每段路上都采用匀速骑行的方式。

分析

在“提示”的提示下,该问题等价于以下最优化问题:

\[\begin{matrix} \min&\displaystyle\sum_{i=1}^ns_iv_i^{-1}\\ \text{s.t.}&\displaystyle\sum_{i=1}^nk_is_i(v_i-v_i')^2=E_U\\ &v_i\in \mathbb R_+&i=1,2,3,\dots,n \end{matrix} \]

第一个条件原本应该是 \(\le E_U\),但是显然取到 \(\min\) 时有 \(=E_U\) 成立。

先忽略 \(v_i\in \mathbb R_+\) 的条件(这实际上是不等式条件),则剩下的部分可以用拉格朗日乘子法解决。记拉格朗日函数:

\[L(v,\lambda)=\sum_{i=1}^ns_iv_i^{-1}+\lambda\left[\sum_{i=1}^nk_is_i(v_i-v_i')^2-E_U\right] \]

现在解决 \(L\) 的无约束最值问题。令其各维偏导为 \(0\):

\[\begin{cases} \frac{\partial}{\partial v_i} L=-s_iv_i^{-2}+2\lambda k_is_i(v_i-v_i')=0&\forall i=1,2,3\dots,n&\\\ \frac{\partial}{\partial \lambda} L=\sum_{i=1}^nk_is_i(v_i-v_i')^2-E_U=0 \end{cases} \]

注意到第一类方程只涉及 \(\lambda\) 和 \(v_i\) 两个变量,我们尝试将 \(v_i\) 解出来,便于代入第二类方程求解。因为 \(v_i\neq 0\),我们可以将其整理成一个三次方程的形式:

\[2\lambda k_i\cdot v_i^2(v_i-v_i')-1=0 \]

注意到在最值点处一定有 \(v_i\ge v_i'\),所以一定有 \(\lambda>0\)。于是可以分离变量:

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

令 \(f_i(x)=x^2(x-v_i')\),讨论 \(f_i\) 的形态:

  • 如果 \(v_i'\le 0\),则 \(x\in (-\infty,0]\) 时 \(f_i(x)\le 0\);\(x\in (0,+\infty)\) 时 \(f_i(x)>0\)。

    因为 \(\frac{1}{2\lambda k_i}>0\),所以 \(f_i(x)=\frac{1}{2\lambda k_i}\) 存在且仅存在正根。更进一步地,根据 \(f_i\) 在 \((0,+\infty)\) 上的单调性可知存在且仅存在唯一正根,这个正根就应该是我们想要的 \(v_i\)。

  • 如果 \(v_i'>0\),则 \(x\in (-\infty,v_i']\) 时 \(f_i(x)\le 0\);\(x\in(v_i',+\infty)\) 时 \(f_i(x)>0\)。

    类似讨论可知,方程存在且仅存在唯一正根,我们取它为 \(v_i\) 即可。

所以,已知 \(\lambda\) 时算出一个 \(v_i\) 可以直接二分或牛顿迭代。令 \(g(\lambda)=\sum_{i=1}^nk_is_i[v_i(\lambda)-v_i']^2-E_U\)。现在我们已经可以求出一个 \(g(\lambda)\),但怎么找出 \(g(\lambda)\) 的根?

简单地分析一下,可以发现 \(\lambda\) 变大时,\(\frac{1}{2\lambda k_i}\) 变小,于是 \(v_i(\lambda)\) 统一变小且保持 \(v_i(\lambda)>v_i'\),于是 \(g(\lambda)\) 也会变小。这就暗示我们 \(g(\lambda)\) 在 \((0,+\infty)\) 上就是单调的。又因为 \(\lambda\) 足够接近 \(0\) 时 \(g(\lambda)>0\),充分大时 \(g(\lambda)<0\),就可以用二分找出根了。


因为我高兴,所以下面是无关紧要的运算:

  • 第一个是 \(f_i(x)=x^2(x-v'_i)\):

    \[f_i'(x)=3x^2-2v_i'x \]

    可见在 \(x>\max\{v_i',0\}\) 时总有 \(f_i'(x)>0\)。

  • 第二个是 \(v_i\)。方程两边同时对 \(\lambda\) 求导:

    \[2k_iv_i^2(v_i-v_i')+6\lambda k_iv_i^2\cdot \frac{\text d v_i}{\text d\lambda}-4\lambda k_iv_i'v_i\cdot \frac{\text d v_i}{\text d\lambda}=0 \]

    可以得到:

    \[\frac{\text dv_i}{\text d\lambda}=\frac{v_i(v_i'-v_i)}{\lambda(3v_i-2v_i')} \]

    因为 \(v_i>\max\{v_i',0\},\lambda>0\),故这个导数始终是 \(<0\) 的。

  • 第三个是 \(g(\lambda)\):

    \[g'(\lambda)=2\sum_{i=1}^nk_is_i(v_i-v_i')\cdot \frac{\text dv_i}{\text d\lambda} \]

    容易发现 \(g'(\lambda)\) 在 \(\lambda>0\) 时始终 \(<0\)。


最后说一说“提示”。不清楚证明它可以不可以先划分成 \(n\) 段(要求每段内部 \(v\) 相同),再证明最值点处全局 \(v\) 相同,再令 \(n\rightarrow +\infty\) 从而产生“极限”。

如果有懂哥的话请教授一下 /kel。

代码

#include <bits/stdc++.h>

#define rep( i, a, b ) for( int i = (a) ; i <= (b) ; i ++ )
#define per( i, a, b ) for( int i = (a) ; i >= (b) ; i -- )

const int NEWTON_ROUND = 30;
const int SEARCH_ROUND = 50;
const int MAXN = 1e4 + 5;

template<typename _T>
inline void Read( _T &x ) {
    x = 0; char s = getchar(); bool f = false;
    while( s < '0' || '9' < s ) { f = s == '-', s = getchar(); }
    while( '0' <= s && s <= '9' ) { x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar(); }
    if( f ) x = -x;
}

template<typename _T>
inline void Write( _T x ) {
    if( x < 0 ) putchar( '-' ), x = -x;
    if( 9 < x ) Write( x / 10 );
    putchar( x % 10 + '0' );
}

double resis[MAXN], dist[MAXN], velo[MAXN];

int N; double E;

inline double FindRoot( const double &a, const double &b ) {
    double u = std :: max( 1., b / a );
    rep( stp, 1, NEWTON_ROUND )
        u = u * ( 1 - ( a * u - b ) / ( 3 * a * u - 2 * b ) ) + 1. / u / ( 3 * a * u - 2 * b );
    return u;
}

inline bool Chk( const double &lamb ) {
    double su = 0;
    rep( i, 1, N ) {
        double c = 2 * lamb * resis[i];
        double v = FindRoot( c, c * velo[i] );
        su += dist[i] * resis[i] * ( v - velo[i] ) * ( v - velo[i] );
    }
    return su >= E;
}

int main() {
    Read( N ); scanf( "%lf", &E );
    rep( i, 1, N ) scanf( "%lf %lf %lf", &dist[i], &resis[i], &velo[i] );
    double x = 0;
    while( true ) {
        if( Chk( x + 1 ) )
            x = x + 1;
        else {
            double l = x, r = x + 1, mid;
            rep( stp, 1, SEARCH_ROUND ) {
                mid = ( l + r ) * 0.5;
                if( Chk( mid ) ) l = mid;
                else r = mid;
            }
            x = l;
            break;
        }
    }
    double ans = 0;
    rep( i, 1, N ) {
        double c = 2 * x * resis[i];
        ans += dist[i] / FindRoot( c, c * velo[i] );
    }
    printf( "%.10f\n", ans );
    return 0;
}

标签:le,frac,double,sum,NOI2012,text,川藏,骑行,lambda
From: https://www.cnblogs.com/crashed/p/17421526.html

相关文章

  • 题解 P3225 [HNOI2012] 矿场搭建
    解析传送门一道简单的tarjan题题意:在无向图中找一些点,这些点组成的的点集记为\(V\),使得去掉任意一个点,剩下的每一个点都可以到达\(V\)中任意一个点,求点集\(V\)的大小的最小值及其方案数。去掉一个点,很自然的联想到割点,那么考虑一下割点在不在备选集合中。如图,显然可以看出,......
  • #Python 利用python计算百度导航骑行距离(第二篇)批量计算
    https://www.cnblogs.com/simone331/p/17218019.html在上一篇中,我们计算了两点的距离(链接为上篇文章),但是具体业务中,往往会存在一次性计算多组,上百甚至上千的距离。所以......
  • P3224 [HNOI2012]永无乡 题解
    典型Splay练习题。开始建\(n\)个Splay,每一次建边用并查集判断是否在一个子图,不在就合并,即把一个Splay的所有点全插入到另一个Splay中,需要合并的点可以用vector存储。但......
  • P3226 [HNOI2012]集合选数
    简要题意给你一个\(n\)个元素的集合,它由前\(n\)个正整数构成。你需要求出它有多少个非空子集,满足若\(x\)在这个子集中,\(2x,3x\)不能在子集中。由于答案可能很大,你......
  • P3225 [HNOI2012]矿场搭建 tarjan
    //题意:在一幅无向图图上,删除一个点后,其他所有点上的人还能通过其他点出去,问最少设置几个出口,以及方案数//思路:无向图就联想到双联通分量,我们来分类讨论一下//1......
  • 洛谷P3224 [HNOI2012]永无乡 题解 splay tree 启发式合并
    题目链接:https://www.luogu.com.cn/problem/P3224主要知识点是:树上启发式合并,即每次合并将小的树里面的每个点合并大大的树里面,时间复杂度\(O(n\log^2n)\)。同时需要......
  • 【题解】P2050 [NOI2012] 美食节
    [NOI2012]美食节题目描述CZ市为了欢迎全国各地的同学,特地举办了一场盛大的美食节。作为一个喜欢尝鲜的美食客,小M自然不愿意错过这场盛宴。他很快就尝遍了美食节所有......
  • P3226 [HNOI2012]集合选数(状压 DP)
    P3226[HNOI2012]集合选数要求选出集合\(S\)满足如果\(x\)选择了,\(2x\)和\(3x\)都不能选择。求\(\{1,2,\dots,n\}\)的符合要求的子集数量。\(n\le10^5\)。......
  • 洛谷P3225 [HNOI2012]矿场搭建
    SLOJH7136.「HNOI2012」矿场搭建题目描述煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援......
  • BZOJ 2733: [HNOI2012]永无乡
    题目链接:​​传送门​​​Description永无乡包含n座岛,编号从1到n,每座岛都有自己的独一无二的重要度,按照重要度可以将这n座岛排名,名次用1到n来表示。某些岛之间......