【BZOJ2876】【Noi2012】骑行川藏 拉格朗日乘法
题目描述
给你 \(n,E,s_i,k_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}\)。
运用拉格朗日乘法,有:
\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】骑行川藏 拉格朗日乘法的更多相关文章
- [BZOJ2876][NOI2012]骑行川藏(拉格朗日乘数法)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2876 分析:就是要求约束条件下函数的极值,于是拉格朗日乘数列方程,发现化简后的关于vi ...
- bzoj 2876: [Noi2012]骑行川藏 拉格朗日数乘
2876: [Noi2012]骑行川藏 Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1033 Solved: ...
- bzoj2876 [NOI2012]骑行川藏(拉格朗日乘数法)
题目描述 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因此在每天的骑行 ...
- bzoj2876 [Noi2012]骑行川藏
Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...
- BZOJ2876 [Noi2012]骑行川藏 【拉格朗日乘数法】
题目链接 BZOJ 题解 拉格朗日乘数法 拉格朗日乘数法用以求多元函数在约束下的极值 我们设多元函数\(f(x_1,x_2,x_3,\dots,x_n)\) 以及限制\(g(x_1,x_2,x_3,\ ...
- 2876: [Noi2012]骑行川藏 - BZOJ
Description 蛋蛋非常热衷于挑战自我,今年暑假他准备沿川藏线骑着自行车从成都前往拉萨.川藏线的沿途有着非常美丽的风景,但在这一路上也有着很多的艰难险阻,路况变化多端,而蛋蛋的体力十分有限,因 ...
- 【bzoj2876】 Noi2012—骑行川藏
http://www.lydsy.com/JudgeOnline/problem.php?id=2876 (题目链接) 题意 在满足约束条件$${\sum_{i=1}^ns_ik_i(v_i-v_i' ...
- bzoj 2876: [Noi2012]骑行川藏【拉格朗日乘数法+二分】
详见: http://blog.csdn.net/popoqqq/article/details/42366599 http://blog.csdn.net/whzzt/article/details ...
- 洛谷P2179 [NOI2012]骑行川藏(拉格朗日乘数法)
题面 传送门 题解 看\(mashirosky\)大佬的题解吧--这里 //minamoto #include<bits/stdc++.h> #define R register #def ...
随机推荐
- Mysql基本操作指令集锦
一.MySQL服务的启动.停止与卸载 在 Windows 命令提示符下运行: 启动: net start MySQL 停止: net stop MySQL 卸载: sc delete MySQL 二. ...
- 林业有害生物监测系统(重庆宇创GIS)
本文由重庆宇创GIS团队原创,转载请注明来源http://www.cnblogs.com/ycdigit/p/8916073.html 一.概述 林业有害生物监测信息平台(森林病虫害监测预警系统) ...
- 微信小程序(四) 模板的使用
模板的使用:单独建立一个页面,在另一个页面通过name属性名调用使用(注意要导入模板路径) template.wxml页面
- vue(1)——node.js安装使用,利用npm安装vue
node node简介 node.js也是用js开发的语言,而且是一门服务端语言,更有大神利用node写了一个操作系统出来——NodeOS node能干什么 自带下载工具: 对于我们开发前端项目,no ...
- 【PAT】B1016 部分A+B
水题 以字符和字符串形式储存输入,比较,计算出两个个数的D的个数,用for循环拼成P,相加得出结果 #include<stdio.h> int main(){ char A[20],DA, ...
- LeetCode算法题-Baseball Game(Java实现)
这是悦乐书的第288次更新,第305篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第156题(顺位题号是682).你现在是棒球比赛点记录器.给定一个字符串列表,每个字符串 ...
- 2017 百度杯丶春秋欢乐赛 writeup
1. 内涵图(Misc) 题目: 我不是一个简单的图片 我是一个有内涵的图片 解:保存到桌面,右键属性->详细信息,即可获得flag. 2. 小电影(Misc) 题目: 我说过 这次比赛是让大家 ...
- Maven的简单使用
Maven使用 在官网下载maven: http://maven.apache.org/download.cgi 解压到D盘(位置随便) 配置环境变量 打开dos窗口,检测是否成功,出现如下画面表示配 ...
- centos下 telnet访问百度
先在命令行输入以下命令: telnet www.baidu.com 80 点击确认之后出现如下界面 然后接着输入以下两行命令 GET /index.html HTTP/1.1 Host: www.ba ...
- Autofs自动挂载探讨
Autofs介绍: mount是用来挂载文件系统的,可以在系统启动的时候挂载也可以在系统启动后挂载.对于本地固定设 备,如硬盘可以使用mount挂载:而光盘.软盘.NFS.SMB等文件系统具有动态性, ...