洛谷P6397

[COI2008] GLASNICI

题意描述

img

输入

3.000
2
0.000
6.000

输出

1.500

点拨

二分答案的题一般来说可以用答案去检验假设。
对于这道题,每一个信使的最佳走法是保证在通信范围内的情况下向右走,否则向左走
由子最优推到全局最优

代码

#include<iostream>
#include<utility>
#include<iomanip>
using namespace std;
typedef long long ll;
#define fi(i,a,b) for(int i = a; i <= b; ++i)
#define fr(i,a,b) for(int i = a; i >= b; --i)
#define x first
#define y second
#define sz(x) ((int)(x).size())
#define pb push_back
using pii = pair<int,int>;
//#define DEBUG
const int N = 1e5 + 5;
double per[N];
int n;
double k;
bool check(double res){
    double temp[N];
    fi(i,1,n) temp[i] = per[i];
    fi(i,1,n){
        if(i == 1){
            temp[i] += res;
            continue;
        }
        double pre = temp[i-1] + k;
        if(temp[i] < pre){
            temp[i] = min(pre,temp[i]+res);
        }
        else if(temp[i] > pre){
            if(temp[i] - res > pre) return false;
            else temp[i] = pre;
        }
    }
    return true;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
#ifdef DEBUG
    //freopen(D:\in.txt,r,stdin);
#endif
    cin >> k >> n;
    fi(i,1,n) cin >> per[i];
    double r = per[n];
    double l = 0;
    while(r - l >= 1e-4){
        double temp = (r + l) / 2;
        if(check(temp)) r = temp;
        else l = temp + 0.0001;
    }
    cout << setprecision(3);
    cout << fixed;
    cout << l << endl;
    return 0;
}
posted @ 2022-03-24 21:48  Sun-Wind  阅读(46)  评论(0编辑  收藏  举报