题目大意
给定整数
n
,浮点数
∙
令
w=⌊n−p1k⌋(p1−p0)+(⌊n−p2k⌋−⌊n−p1k⌋)(p2−p0)
,其中
p1、p2
为自变量,要求最大化函数
w
,且
其中 n≤106 , 0.1≤k≤10 , p0>0
题目分析
这题出成中考题一定很爽。
Algorithm 1:枚举+三分
由于下取整里面的东西要大于等于
0
,所以其最多有
而且对于一个固定的下取整那一项,第一问中显然
p
越大越优,第二问(固定第一个下取整)中
时间复杂度
O(nlog1.5n)
Algorithm 2:三分套三分
第一问显然可以三分解决。
第二问我们将其化成另一个形式:
w=⌊n−p1k⌋(p1−p2)+⌊n−p2k⌋(p2−p0)
。
我们拆开来考虑:当
p2
固定时,前面部分是单峰函数,满足三分的性质。然后我们考虑
p2
的变化,可以发现,当
p2
递增的时候,前面部分的最大值是满足单调不递增的(易证),后面部分是单峰函数。因此,
w
是一个单峰函数加上一个单调不递增函数,显然我们找到单峰函数的峰,它左边部分是单调不递减加上一个单调不递增函数,于是这就变成一个单峰函数,可以三分;右边部分都是单调不递增,加起来显然是单调不递增函数,不会比左边优。所以我们三分找峰顶,在峰顶分成两部分,对左边进行三分即可。
时间复杂度
Algorithm 3:奇怪的结论解法
数形结合,将函数图像画出来,发现是一个一次函数在第一象限内的线段,求上面某(两)点与坐标轴围成矩形面积(之和)。
第一问是线段中点,第二问线段三等分点。证明自证。
时间复杂度
O(1)
。
(Water)Algorithm 4:二分法
初一某水军使用二分水了过去,我无言以对,数据太强了没办法。
—————————————–我是萌萌哒分割线—————————————–
经过多方查证,我终于听闻了传说中二分求峰法。
二分出中点,然后在中点两边合适精度的地方取点,比较大小,转换区间。
首先这样做如果两边值大小相等,选哪边就变成了玄学。
其次精度开的不够好会被抖出峰顶,开高精度要牺牲时间复杂度。
当然其在随机数据下表现良好。
代码实现
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
printf("题目还没有数据,等到数据来了,切出来再放标程。");
return 0;
}