题目描述

  给你 \(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. 通过Xtrabackup实现MySQL实例的全库备份与按需单库恢复

    在实际的生产环境中,为了管理方便,我们一般是通过 Xtrabackup实现实例的全库备份,即将实例上的所有数据库备份. 但是,考虑到快速恢复 我们常常面临的需求是快速还原单个数据库.针对初学者来说,网 ...

  2. C#-事件event

    目录 1. 简介 2.实际案例 2.1实际案例1 2.2实际案例2--带有参数的事件 3.标准事件的用法 3.1通过扩展EventArgs来传递数据 3.2代码实例 1. 简介 事件是一种类型安全的委 ...

  3. AngularJS学习之旅—AngularJS Select(十)

    1.AngularJS Select(选择框) AngularJS 可以使用数组或对象创建一个下拉列表选项. ng-option:创建一个下拉列表,列表项通过对象和数组循环输出 eg: <div ...

  4. SQLServer之修改DEFAULT约束

    使用SSMS数据库管理工具修改DEFAULT约束 1.连接数据库.选择数据表->右键点击->选择设计. 2.在表设计器窗口->选中要修改的数据列->在列属性中找到默认值绑定-& ...

  5. Vim 宏

    宏的概念 什么是宏呢?英文名:macro,代表一串命令的集合. 示例操作文本 SELECT * FROM `edu_ocr_task` WHERE ((`userId`=284871) AND (`u ...

  6. easyui中datagrid+layout布局

    1.掌握layout布局 首先,layout布局的具体使用可参考官网http://www.jeasyui.net/plugins/162.html layout布局分为东南西北中五个区域,如图我们将其 ...

  7. 一个Web项目中实现多个数据库存储数据并相互切换用过吗?

    最近公司一个项目需要连接多个数据库(A和B)操作,根据不同的业务模块查询不同的数据库,因此需要改造下之前的spring-mybatis.xml配置文件以及jdbc.properties配置文件,项目后 ...

  8. Configuring High Availability and Consistency for Apache Kafka

    To achieve high availability and consistency targets, adjust the following parameters to meet your r ...

  9. ThreadPoolExecutor解析

    前言:在最新的阿里规范中强制使用ThreadPoolExecutor方式创建线程池,不允许使用Executors,因此有必要对ThreadPoolExecutor进行进一步了解. 1.ThreadPo ...

  10. 查看jar包的jdk版本