题目描述

  给你 \(n,E,s_i,k_i,v_i'\),要求在

\[\sum_{i=1}^nk_i{(v_i-v_i')}^2s_i\leq E
\]

的前提下最小化

\[\sum_{i=1}^n\frac{s_i}{v_i}
\]

  \(n\leq 10000,0\leq E\leq {10}^8,0<s_i\leq {10}^5,0<k\leq 1,-100<v_i'<100\)

题解

  显然最优解会把体力浪完,所以约束的不等号可以换成等号。

  这样就变成了:在 \(G(V)=\sum_{i=1}^nk_i{(v_i-v_i')}^2s_i-E=0\) 的前提下最小化 \(F(V)=\sum_{i=1}^n\frac{s_i}{v_i}\)。

  运用拉格朗日乘法,有:

\[\begin{cases}
\sum_{i=1}^nk_i{(v_i-v_i')}^2s_i-E=0\\
\frac{s_i}{x_i^2}=2\lambda k_is_i(x_i-v_i)
\end{cases}
\]

  每个方程左边都是一个在第一象限的双曲线,右边是一条直线。

  所以一定有一个交点,且 \(\lambda>0\)。

  可以看出,当 \(\lambda\) 增大时,\(v_i\) 会减小,\(G\) 也会减小,所以 \(G\) 随 \(\lambda\) 递减。

  所以我们只需要二分 \(\lambda\),再二分 \(v_i\),判断 \(G\) 的负号即可。

  时间复杂度:\(的二分次数的二分次数O(n\times \lambda\text{的二分次数}\times v_i\text{的二分次数})\)

  二分上界我也不会算,就随便输了一个\({10}^{10}\)

  这题精度要求比较高,\(eps\)要设为\({10}^{-14}\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
if(a>b)
swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
int rd()
{
int s=0,c,b=0;
while(((c=getchar())<'0'||c>'9')&&c!='-');
if(c=='-')
{
c=getchar();
b=1;
}
do
{
s=s*10+c-'0';
}
while((c=getchar())>='0'&&c<='9');
return b?-s:s;
}
void put(int x)
{
if(!x)
{
putchar('0');
return;
}
static int c[20];
int t=0;
while(x)
{
c[++t]=x%10;
x/=10;
}
while(t)
putchar(c[t--]+'0');
}
int upmin(int &a,int b)
{
if(b<a)
{
a=b;
return 1;
}
return 0;
}
int upmax(int &a,int b)
{
if(b>a)
{
a=b;
return 1;
}
return 0;
}
const double eps=1e-14;
int n;
double a[10010],k[10010],s[10010],v[10010];
double E;
void getv(double x)
{
for(int i=1;i<=n;i++)
{
double l=0,r=1e10;
while(r-l>eps)
{
double mid=(l+r)/2;
double s1=s[i]/mid/mid;
double s2=2*x*k[i]*s[i]*(mid-a[i]);
if(s1>s2)
l=mid;
else
r=mid;
}
v[i]=l;
}
}
double calc(double x)
{
getv(x);
double ans=0;
for(int i=1;i<=n;i++)
ans+=k[i]*s[i]*(v[i]-a[i])*(v[i]-a[i]);
return ans;
}
int main()
{
open("bzoj2876");
scanf("%d%lf",&n,&E);
for(int i=1;i<=n;i++)
scanf("%lf%lf%lf",&s[i],&k[i],&a[i]);
double l=0,r=1e10;
while(r-l>eps)
{
double mid=(l+r)/2;
if(calc(mid)>E)
l=mid;
else
r=mid;
}
getv(l);
double ans=0;
for(int i=1;i<=n;i++)
ans+=s[i]/v[i];
printf("%.10lf\n",ans);
return 0;
}

【BZOJ2876】【Noi2012】骑行川藏 拉格朗日乘法的更多相关文章

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

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

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

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

  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. 2876: [Noi2012]骑行川藏 - BZOJ

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

  7. 【bzoj2876】 Noi2012—骑行川藏

    http://www.lydsy.com/JudgeOnline/problem.php?id=2876 (题目链接) 题意 在满足约束条件$${\sum_{i=1}^ns_ik_i(v_i-v_i' ...

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

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

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

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

随机推荐

  1. 0.react学习笔记-环境搭建与脚手架

    0.环境搭建 笔者使用的是deepin/mac两种系统,因为两个电脑经常切换用.环境搭建没什么区别. 0.1 node安装 按照node官网叙述安装 # Using Debian, as root c ...

  2. 从.Net到Java学习第十一篇——SpringBoot登录实现

    从.Net到Java学习系列目录 通过前面10篇文章的学习,相信我们对SpringBoot已经有了一些了解,那么如何来验证我们的学习成果呢?当然是通过做项目来证明啦!所以从这一篇开始我将会对之前自己做 ...

  3. 简易仿ios菊花加载loading图

    原文链接:https://mp.weixin.qq.com/s/wBbQgOfr59wntNK9ZJ5iRw 项目中经常会用到加载数据的loading显示图,除了设计根据app自身设计的动画loadi ...

  4. Git:五、操作远程仓库

    0.一般流程 1)自己新写:GitHub创建有README的库 -> clone到本地 2)修改已有:GitHub上fork别人的仓库 -> clone自己账号下的库到本地 1.创建库 右 ...

  5. whistle

    whistle介绍 whistle是基于Node的跨平台web调试代理工具, 主要查看, 修改HTTP, HTTPS, Websocket的请求,响应, 也可以作为HTTP代理服务器使用 (文档)[h ...

  6. Nagle 算法

    1. Nagel算法        TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认.为了尽可能的利用网络带宽,TCP总是希望尽可能的发 ...

  7. oracle 10g函数大全--日期型函数

    sysdate [功能]:返回当前日期. [参数]:没有参数,没有括号 [返回]:日期 [示例]select sysdate hz from dual; 返回:2008-11-5 add_months ...

  8. 我的第一个python web开发框架(28)——定制ORM(四)

    在数据库操作时,新增记录也是必不可少的,接下来我们应用字典的特性来组合sql语句 先上产品新增接口代码 @post('/api/product/') def callback(): "&qu ...

  9. idea spring-boot总结

    1. 按自己重新配置spring-boot pom点进 mybatis-spring-boot-starter ,在要改的里面 <version>3.4.4</version> ...

  10. TortoiseGit之配置密钥

    TortoiseGit 使用扩展名为ppk的密钥,而不是ssh-keygen生成的rsa密钥.使用命令ssh-keygen -C "邮箱地址" -t rsa产生的密钥在Tortoi ...