洛谷P6397
[COI2008] GLASNICI
题意描述
输入
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;
}