[BZOJ2876] [NOI2012] 骑行川藏 - 数论 - 拉格朗日定理(拉格朗日乘子法) + 二分
2016-05-08 20:39
435 查看
[ 题外话 : = =看了一眼题目就知道是求最值
然后就不会做了╮(╯▽╰)╭
所以,数学渣就去学了一发拉格朗日乘数法 - -]
那么上正文TAT 由于公式太多,我就直接截图哈qwq
附代码:
#include "stdio.h"
#include "iostream"
#define rep(f,a,b) for(f=a;f<=b;f++)
using namespace std;
const double eps=1e-12;
const double inf=1e5;
const int N=10005;
void read(int &v){
char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar();
while (ch<='9'&&ch>='0') { v=v*10+ch-'0'; ch=getchar();}
}
int n; double eu;
double s
,k
,vi
;
double v
,atime,lagra;
double speed(double y,int t,double &x){
double bot=max(0.0,y),top=inf;
while (x=(bot+top)/2,top-bot>eps){
if (2*lagra*k[t]*x*x*(x-y)<=1) bot=x; else top=x;
}
}
bool check(){
int i; double esum=0.0;
rep(i,1,n) {
speed(vi[i],i,v[i]);
esum+=k[i]*(v[i]-vi[i])*(v[i]-vi[i])*s[i];
}
return esum>=eu;
}
int main(){
//freopen("bicycling.in","r",stdin);
//freopen("bicycling.out","w",stdout);
read(n); int i;
scanf("%lf",&eu);
rep(i,1,n) {
scanf("%lf%lf%lf",s+i,k+i,vi+i);
} double bot=0.0,top=inf;
while (lagra=(bot+top)/2,top-bot>eps){
if (check()) bot=lagra;
else top=lagra;
}
rep(i,1,n) atime+=s[i]/v[i];
printf("%.10lf\n",atime);
return 0;
}
相关文章推荐
- 1.m分解阶乘之和
- 2.几种递推数
- 3.欧拉函数
- 4.快速幂模m算法
- 5.扩展欧几里得&&中国剩余定理
- 6.数论_web
- Project Euler Problem 387 - Harshad Numbers - 深度优先
- 编程之美2015初赛A
- 数论题集
- 原根
- 阶与原根学习笔记
- HDU 1299 Diophantus of Alexandria
- Leftmost Digit(HDU 1060)
- Rightmost Digit(HDU 1061)
- Python-在奇数中寻找素数
- ZOJ 2674 Strange Limit 欧拉定理
- LeetCode-Palindrome Number
- 组合数求模总结
- Sicily 1047 Super Snooker
- 【数论】组合数求模