算法介绍
- 算法简介:三分法适用于以O($logn$)复杂度求解单峰函数的最值,平均每次舍去$1/3$的定义域。
- 适用条件:
- 有界性:有明确的初始定义域。
- 单峰性:仅存在一个目标最值,且最值两侧的函数单调。
(注:二分法用于求解单调函数零点,三分法用于求解单峰函数最值,二者思想相似,但适用条件有本质区别)
- 实现细节:
- 确定初始区间$l,r$。
- 找到三等分点$m1,m2$,求出函数在这两点的函数值$f1,f2$。
- 比较$f1,f2$,将其中与最值方向相反的三等分点,所在的$1/3$定义域舍去。(详解见下,可配合画图理解)
模板分析
Deadline(CF1288A)
- 题意:一个程序被要求在n天以内得出结果,但它实际得出结果却需要运行d天。你可以花费x天优化程序,使程序实际运行所需时间降为${d} \over {x+1}$(向上取整)。输入t组数据,判断能否在n天以内得出结果。
- 分析:不考虑函数值的取整,实际花费总时间$f(x)=x+$ ${d} \over {x+1}$。由均值不等式可得,该函数为有最小值的单峰函数,可用三分法求出最小值。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
inline int get_min(int n,int d)
{
double l=0,r=n,m1,m2,f1,f2;//有界性,0<=x<=n
while(r-l>1e-2)
{
m1=l+(r-l)/3;
m2=r-(r-l)/3;//求出三等分点
f1=m1+d/(m1+1);
f2=m2+d/(m2+1);
if(f1>f2)l=m1;//*舍弃与最值方向相反的三等分点,所在的1/3区间
else r=m2;
}
return min((int)l+ceil((double)d/((int)l+1)),ceil(l)+ceil((double)d/(ceil(l)+1)));//返回最小整数解
}
inline void solve()
{
int n,d;
scanf("%d %d",&n,&d);
d=get_min(n,d);
if(d<=n)printf("YES\n");
else printf("NO\n");
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
solve();
return 0;
}
原文地址:https://www.cnblogs.com/-SingerCoder/p/12422427.html
时间: 2024-10-08 22:59:57