欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[BZOJ2876][Noi2012]骑行川藏(二分答案+拉格朗日乘数法)

程序员文章站 2024-03-17 16:52:28
...

Address

https://www.lydsy.com/JudgeOnline/problem.php?id=2876

Solution

为了方便某些萌新,讲下拉格朗日乘数法。
作用:求多元函数 f(x1,x2,...,xn) 在约束 ϕ(x1,x2,...,xn)=0 下的极值。引入变量 λ ,令拉格朗日函数:

F(x1,x2,...,xn,λ)=f(x1,x2,...,xn)+λϕ(x1,x2,...xn)

F 的每个变量(包括 λ )分别求偏导。
(事实上对 λ 求偏导后的结果就是 ϕ(x1,x2,...,xn)
(多元函数 F 对一个自变量 x 的偏导数,定义为将 Fx 之外的自变量全部视为常数后对 F 求导)
F 对每个自变量的偏导数都等于 0 时,
f(x1,x2,...,xn) 在约束 ϕ(x1,x2,...,xn)=0 下取得极值。
回到原问题。
发现体力不是一个标准的约束。
但如果体力没用完,则一定可以在某一天速度更快。
所以,存在一种最优方案使得体力恰好用完
同样我们也能得到,存在一种最优方案使得对于每个 ivivi
vi 表示第 i 天实际速度)
目标函数:
f(v1,v2,...,vn)=i=1nsivi

约束条件:
ϕ(v1,v2,...,vn)=EUi=1nki(vivi)2si=0

引入系数 λ ,构造拉格朗日函数:
i=1n(sivi+λki(vivi)2si)EU

vi 求偏导得到:
sivi2+λki(2vi2vi+vi2)si

要求上式为 0
1vi2+λki(2vi2vi)=0

2λki(vivi)vi2=1

易得上式左边在 vivi 即上式左边的值大于等于 0 时单调递增。
故在 λ 确定时二分答案可以算出 vi
同时, λ 越大, vi 越小。
所以 λ 的值也可以二分,通过 ϕ(v1,v2,...,vn) 的值来调整 λ
最后得出了 λ 的值之后就能计算取到极值时的 vi

Code

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define For(i, a, b) for (i = a; i <= b; i++)
using namespace std;
const int N = 1e4 + 5;
const double eps = 1e-12;
int n;
double eu, k[N], s[N], vp[N], ans;
double vsol(double lambda, int i) {
    double l = max(vp[i], 0.0), r = 1e5;
    while (r - l > eps) {
        double mid = (l + r) / 2, val;
        val = 2.0 * lambda * k[i] * (mid - vp[i]) * mid * mid;
        if (val < 1) l = mid;
        else r = mid;
    }
    return (l + r) / 2;
}
double calc(double lambda) {
    int i; double res = 0, tmp;
    For (i, 1, n) tmp = vsol(lambda, i),
        res += k[i] * s[i] * (tmp - vp[i]) * (tmp - vp[i]);
    return res;
}
int main() {
    int i;
    double x, y, lambda, l = 0, r = 1e5;
    cin >> n >> eu;
    For (i, 1, n) scanf("%lf%lf%lf", &s[i], &k[i], &vp[i]);
    while (r - l > eps) {
        double mid = (l + r) / 2;
        if (calc(mid) > eu) l = mid;
        else r = mid;
    }
    For (i, 1, n) ans += s[i] / vsol((l + r) / 2, i);
    printf("%.10lf\n", ans);
    return 0;
}
相关标签: 二分答案