Stay Hungry,Stay Foolish!

D - Freefall -- ATCODER

D - Freefall

https://atcoder.jp/contests/abc279/tasks/abc279_d

思路

求凹函数的极小值

 

 https://www.cnblogs.com/luoyj/p/12408277.html#6

#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
int n;
double a[15];
double f(double x){       //计算函数值
    double s=0;
    for(int i=n;i>=0;i--) //注意函数求值的写法
        s = s*x + a[i];
    return s;
}
int main(){
    double L,R;
    scanf("%d%lf%lf",&n,&L,&R);
    for(int i=n;i>=0;i--) scanf("%lf",&a[i]);
    while(R-L > eps){  // for(int i = 0; i<100; i++){   //用for也行
        double k =(R-L)/3.0;
        double mid1 = L+k, mid2 = R-k;
        if(f(mid1) > f(mid2)) 
               R = mid2;
        else   L = mid1;
    }
    printf("%.5f\n",L);
    return 0;
}

 

Code

https://atcoder.jp/contests/abc279/submissions/36900883

#include <bits/stdc++.h>
using namespace std;

long long a, b;

long double get_t(long long x){
    long double ret = 0;
    ret = (long double)b*x + (long double)a/sqrt(x+1);
    
    return ret;
}

int main(){
    cout << fixed << setprecision(10);
    
    cin >> a >> b;
    
    long long l, r;
    l = 0;
    r = a;
    
    while(l < r){
//        cout << "---------------" << endl;
//        cout << "l = " << l << endl;
//        cout << "r = " << r << endl;
        
        long long len = r - l;
        long long one = len / 3;
        if (one == 0){
            break;
        } 
        
//        cout << "one = " << one << endl;
        
        long long mid1 = l + one;
        long long mid2 = r - one;
        
//        cout << "mid1 = " << mid1 << endl;
//        cout << "mid2 = " << mid2 << endl;
        
        if (mid1 >= mid2){
            break;
        }
        
        long double mid1v = get_t(mid1);
        long double mid2v = get_t(mid2);

//        cout << "mid1v = " << mid1v << endl;
//        cout << "mid2v = " << mid2v << endl;

        if(mid1v <= mid2v){
            r = mid2;
        } else if (mid1v > mid2v){
            l = mid1;
        } else {
            
        }
    }
    
    long long mini = l;
    long double minv = get_t(mini);
    for(long long i=l-10; i<=r+10; i++){
        long double cv = get_t(i);
        if(cv < minv){
            mini = i;
            minv = cv;
        }
    }

    cout << minv << endl;
}

微积分法

 

 

https://atcoder.jp/contests/abc279/submissions/36813100

void solve() {
    double a,b,aa;
    cin>>a>>b;
    aa=a;
    a/=b;
    a/=2;
    double c=pow(a,0.6666666666)-1;
    double d1=ceil(c),d2=floor(c);
    double ans=min(d1*b+aa/sqrt(d1+1.0),d1*b+aa/sqrt(d2+1.0));
    printf("%.09lf",ans);
    ret;
}
 
signed main() {
    int t = 1;
    nfr(i, t) {
        solve();
    }
    ret 0;
}

 

posted @ 2022-11-27 22:34  lightsong  阅读(96)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel