CF924B Three-level Laser 题解
题目分析
主要思路:枚举每个 $i$,求出对应最佳情况的 $j$ 和 $k$,取最大值。
-
当 $i$,$k$ 固定时,显然 $E_k-E_i$ 为定值。此时 $E_k-E_j$ 应取最大值,即 $E_j$ 取最小值,$j$ 应取最小值为 $i+1$。
-
当 $i$,$j$ 固定时,$\frac{E_k-E_j}{E_k-E_i} $ 取最大值当且仅当 $E_k$ 取得最大值且 $E_k - E_i \le U$。具体证明见下。这一步可以用二分解决。
证明:$\frac{E_k-E_j}{E_k-E_i} $ 取最大值当且仅当 $E_k$ 取得最大值。
假设存在 $E_{k_1} < E_{k_2},x = E_{k_2} - E_{k_1}$ 使得:
$$\frac{E_{k_1}-E_j}{E_{k_1}-E_i} > \frac{E_{k_2}-E_j}{E_{k_2}-E_i} $$
换元简化式子可得:
$$\frac{a}{b} > \frac{a+x}{b+x} (a > 0,b>0,x>0) $$ 进一步化简得:$$a > b$$ 显然矛盾,故假设不成立,原命题成立。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
int n,k,a[N];
double res = -1;
int find(int i)
{
int x = a[i]+k,l = i+2,r = n;
while (l < r) // 二分
{
int mid = l + r + 1 >> 1;
if (a[mid] <= x) l = mid;
else r = mid-1;
}
if (a[l] <= x) return l;
else return -1;
}
int main()
{
scanf("%d%d",&n,&k);
for (int i = 1;i <= n;i++) scanf("%d",&a[i]);
for (int i = 1;i <= n-2;i++)
{
int x = find(i);
if (x == -1) continue; // i j k 分别为 i i+1 x
res = max(res,1.0*(a[x]-a[i+1])/(a[x]-a[i]));
}
if (res < 0) puts("-1"); //不存在
else printf("%.10f",res);
return 0;
}

浙公网安备 33010602011771号