一个能看的题解!预备知识只有高中数学的【导数】。不用什么偏导数/拉格朗日乘子法之类的我看不懂的东西( •̀∀•́ )!

如果你不知道什么是导数,可以找本高中数学选修2-2来看一下!看第一章第1、2节就好啦。传送门:选修2-2


感性理解一下这道题:

一开始,我们可以给所有路段随便分配一个速度。

接下来,我们需要在一些路段上耗费一定能量用来提速,以此缩短一定时间。不同路段上,花费单位能量能缩短的时间(简称“性价比”)是不同的,所以如果我们要模拟这个过程,一定是每时每刻都在当前性价比最高的路段上花费能量,直到能量花完为止。(似乎……也可以花费负的能量,增加某路段所需时间,然后把能量用到别的地方去。)

注意到一个性质:随着花费能量增加,性价比会越来越低。

这样的话,只要按照上面这种贪心策略,时时刻刻在性价比最高的路段花费能量(并使它的性价比降低),最后达到最优解时,各路段性价比会一样

暴力模拟似乎是写不出来的,考虑更正常的做法。

这个性价比是什么呢?如果我们对每段路画出一个\(t-E\)函数图象,表示该路段需要的时间\(t\)花费的能量\(E\)的函数关系,那么花费一定能量\(e\)之后的“性价比”是什么呢?就是函数图像上横坐标为\(e\)处切线的斜率——导数。

那么最优解就满足——各路段导数一样!

同时,这个公共导数(是负的)绝对值越小(性价比越低),所需能量越多,总时间越小。

于是二分这个导数,求出每段速度,以此求出所需能量,和手里的总能量比较一下,就可以二分得到答案了!


以上是思路。现在开始数学。

要求出每段导数关于\(v\)的关系。

对于一段路来说(方便起见,把\(k\)乘上\(s\)作为新的\(k\),就可以少写一个字母了2333):

\[E = k(v - v')^2
\]

\[t = \frac{s}{v}
\]

那么

\(\frac{dt}{dE}\)

$=\frac{dt}{dv} / \frac{dE}{dv} $

\(= -\frac{s}{v^2} / 2k(v - v')\)

\(= -\frac{s}{2kv^2(v-v')}\)

然后二分公共导数\(x\),对于每段路解方程\(-\frac{s}{2kv^2(v-v')} = x\)(可二分)得到\(v\),进而求出需要的能量。


代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#define enter putchar('\n')
#define space putchar(' ')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c < '0' || c > '9')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op == 1) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
} const int N = 10005, INF = 0x3f3f3f3f;
int n;
double E, s[N], k[N], u[N]; double getv(double x, int i){
double l = max(u[i], double(0)), r = 100005, mid;
int cnt = 60;
while(cnt--){
mid = (l + r) / 2;
if(2 * k[i] * x * mid * mid * (mid - u[i]) > -s[i]) l = mid;
else r = mid;
}
mid = (l + r) / 2;
return (l + r) / 2;
}
double calc(double x){
double sum = 0;
for(int i = 1; i <= n; i++){
double v = getv(x, i);
sum += k[i] * (v - u[i]) * (v - u[i]);
}
return sum;
} int main(){ scanf("%d%lf", &n, &E);
for(int i = 1; i <= n; i++)
scanf("%lf%lf%lf", &s[i], &k[i], &u[i]), k[i] *= s[i];
double l = -INF, r = 0, mid;
int cnt = 100;
while(cnt--){
mid = (l + r) / 2;
if(calc(mid) <= E) l = mid;
else r = mid;
}
mid = (l + r) / 2;
double ans = 0;
for(int i = 1; i <= n; i++)
ans += s[i] / getv(mid, i);
printf("%.10lf\n", ans); return 0;
}

[NOI2012] 骑行川藏 | 求导 二分的更多相关文章

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

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

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

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

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

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

  4. bzoj2876 [Noi2012]骑行川藏

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

  5. BZOJ2876 [Noi2012]骑行川藏 【拉格朗日乘数法】

    题目链接 BZOJ 题解 拉格朗日乘数法 拉格朗日乘数法用以求多元函数在约束下的极值 我们设多元函数\(f(x_1,x_2,x_3,\dots,x_n)\) 以及限制\(g(x_1,x_2,x_3,\ ...

  6. [NOI2012]骑行川藏——拉格朗日乘子法

    原题链接 不会啊,只好现学了拉格朗日乘子法,简单记录一下 前置芝士:拉格朗日乘子法 要求\(n\)元目标函数\(f(x_1,x_2,...,x_n)\)的极值,且有\(m\)个约束函数形如\(h_i( ...

  7. bzoj 2876: [Noi2012]骑行川藏【拉格朗日乘数法+二分】

    详见: http://blog.csdn.net/popoqqq/article/details/42366599 http://blog.csdn.net/whzzt/article/details ...

  8. 【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'\),最小化$ \ ...

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

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

随机推荐

  1. 51Nod 1668 非010串

    这是昨天上课ChesterKing dalao讲线代时的例题 当时看到这道题就觉得很水,记录一下后面两位的情况然后讨论一下转移即可 由于之前刚好在做矩阵题,所以常规的矩阵快速幂优化也很简单 好我们开始 ...

  2. 事务,acid,cap,paxos随笔

    事务ACID四个特性: A:原子性(Atomicity)C:一致性(Consistency)I:隔离性(Isolation)D:持久性(Durability) 原子性:语句要么全执行,要么全不执行,是 ...

  3. Object-Oriented(二)原型对象

    自用备忘笔记 1. 理解原型对象 只要创建函数,函数上就会创建一个 prototype 属性指向函数的原型对象. function Person() {} Person.prototype //指向该 ...

  4. 金蝶PDA金蝶盘点机金蝶仓库条码管理方案-采购入库单教程

    采购入库单有两种做法: 第一种:按照采购订单下推的采购入库单. 第二种:直接新增采购入库单,也就是不按照采购订单下推. 按照采购订单下推生成采购入库单,会以采购订单的商品品种和数量作为应收.扫描条码入 ...

  5. Cobbler自动化批量安装Linux操作系统 - 运维总结

    一.Cobbler简述 Cobbler是一个自动化和简化系统安装的工具,通过使用网络引导来控制和启动安装.Cobbler的特性包括存储库镜像.Kickstart模板和连接电源管理系统.Cobbler通 ...

  6. 20135218 Linux 实践二 编译模块

    20135218 姬梦馨 1.编写模块代码 模块构造函数:执行insmod或modprobe指令加载内核模块时会调用的初始化函数.函数原型必须是module_init(),括号内是函数指针 模块析构函 ...

  7. 20135316王剑桥Linux内核学习记笔记第七周

    20135316王剑桥<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC 1000029000 一.可执行程序是怎么得来的? 编译 ...

  8. LINUX第三次实践:程序破解

    LINUX第三次实践:程序破解 标签(空格分隔): 20135328陈都 一.掌握NOP.JNE.JE.JMP.CMP汇编指令的机器码 NOP:NOP指令即"空指令".执行到NOP ...

  9. warning C4996: 'strcpy': This function or variable may be unsafe.

    mkdir 写成  _mkdir strcpy 写成为 strcpy_s 或是在项目处右击-->属性-->C/C++-->预处理器-->在预处理器定义后添加";_CR ...

  10. JWT验证

    理解 JSON Web Token(JWT) 验证 JSON Web Token认证的操作指南 在本文中,我们将了解JSON Web Token的全部内容. 我们将从JWT的基本概念开始,然后查看其结 ...