[BZOJ2876] [NOI2012] 骑行川藏 - 数论 - 拉格朗日定理(拉格朗日乘子法) + 二分




    [ 题外话 :          = =看了一眼题目就知道是求最值

      然后就不会做了╮(╯▽╰)╭ 所以,数学渣就去学了一发拉格朗日乘数法 - -]

    那么上正文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[N],k[N],vi[N];
double v[N],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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值