zoukankan      html  css  js  c++  java
  • [NOI2012]骑行川藏

    [NOI2012]骑行川藏

    思路一:二分导数

    http://www.cnblogs.com/RabbitHu/p/9019762.html

    考虑“性价比”即花费单位能量缩短的时间。

    如果我们给每一段随机分配一个速度,再调整

    那么一定选择性价比最高的调整,或者把性价比较低的能量取回,再分配

    而性价比随着能量分配,会越来越低

    可以发现的是,最后所有的n段的性价比一定都相同!

    (如果存在不同的,那么一定可以从性价比较低的收回一些能量,给性价比高的用,使得总时间更少)

    由于实数范围,所以暴力模拟用个堆什么的不现实

    考虑用数学方法:

    每段的t-E图像是一个类反比函数

    每个点的斜率就是当前能量的性价比!

    就是$e_i$位置的导数

    也即,最后的所有图像$e_i$的导数都是一样的!(并且都是负数)

    而且可以发现,最后导数负数绝对值越小(导数越大),那么花费的总能量越多,时间越短

    所以有二分的性质!

    二分导数,考虑怎么检验

    直观的想法是求出t-E的导数关于E的函数,,,没法求

    但是,t和v的图像的导数就是y=si/x的导数可以求,E和v的导数根据关系式可以直接求

    所以考虑通过v作为中介,求出t-E的导数关于v的函数

    (看上面博客)然后就得到了式子,对于二分的导数,解方程求出$v_i$,再求出$e_i$,通过e的总和判断二分走向

    至于解方程,就用二分即可。(由于等式一边是正数,所以一定有$v_i>v_i'$)

    一些精度问题:(本题精度要求还是比较高的)

    1.二分解方程判断的时候,能不用除法就不要用除法!但是不等式记得变号!(因为x小于零)

    2.eps 1e-14(也可以不用eps,二分100次左右就结束(看人品。。。))

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define reg register int
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const int N=1e4+4;
    const double eps=1e-14;
    double ans;
    double s[N],vi[N],k[N];
    int n;
    double eu;
    double jie(double x,int i){
        double l=max(vi[i],(double)0),r=100000.0;
        double ret=0.00;
        int cnt=60;
        while(r-l>eps){
            double mid=(l+r)/2;
            if(mid*mid*(mid-vi[i])*2*k[i]*x<=-1) r=mid;
            else l=mid;
        }
        ret=(l+r)/2;
        return ret;
    }
    double che(double mid){
        double sum=0;
        for(reg i=1;i<=n;++i){
            double v=jie(mid,i);
            sum+=k[i]*s[i]*(v-vi[i])*(v-vi[i]);
        }
        return sum;
    }
    int main(){
        rd(n);
        scanf("%lf",&eu);
        for(reg i=1;i<=n;++i){
            scanf("%lf%lf%lf",&s[i],&k[i],&vi[i]);
        }
        double r=0.0,l=-100000000.00;
        int cnt=100;
        while(r-l>eps){
            double mid=(l+r)/2.0;
            double now=che(mid);
            if(now<=eu) l=mid;
            else r=mid;
        }
        double mid=(l+r)/2.0;
        for(reg i=1;i<=n;++i){
            ans+=s[i]/jie(mid,i);
        }
        printf("%.10lf",ans);
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/2/5 11:36:13
    */

    思路二:拉格朗日乘数法

    咕咕咕

  • 相关阅读:
    [DFNews] Nuix公司推出培训及认证体系
    [CFNews] Oxygen官方对于新版XRY与之冲突问题的官方解释
    [DFNews] FBI Documents Shine Light on Clandestine Cellphone Tracking Tool
    [CFNews] Be first to get Oxygen Forensic Suite 5.0 just before the End of the World!
    [DFNews] CelleBrite发布2013年移动设备取证趋势与预测白皮书
    [转载] Retrieving Data from an iPhone Voicemail Database
    [转载] 我们从未改变:弱密码仍是最常用的密码
    [DFNews] US students get cracking on Chinese malware code
    [转载] 25GPU cluster cracks every standard Windows password in <6 hours
    [手机取证] Forwarding SMS to Email on [Jailbroken] iOS
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10352649.html
Copyright © 2011-2022 走看看