二分法求最值(HDU2899)

题目链接。题目就是给出一个关于x的多项式,其中y是参数,给定任意的y求出这个多项式的最小值。我们首先观察y的范围就可以知道,x一定是在[0,100]之间的数字,求这个多项式的最小值,当然是当这个多项式对应的函数的导函数的等于零的时候最可以取得最值(当然这句话是很不严谨的,导函数等于零只是函数取最值的必要条件,但是在这个题中可以这么说)。我们可以首先对这个函数求导,求导之后二分出零点,带入原方程就可以了。

#include<iostream>
#include<cmath>
#define ll long long
using namespace std;
const double ebp = 1e-6;
double fun(double x)
{
	return 42 * pow(x, 6) + 48 * pow(x, 5) + 21 * pow(x, 2) + 10 * x;
}
double ans(double x,double y)
{
	return 6 * pow(x, 7) + 8 * pow(x, 6) + 7 * pow(x, 3) + 5 * pow(x, 2) - y * x;
}
double solve(double y)
{
	double l = 0;
	double r = 110;
	while (r - l > ebp)
	{
		double mid = (l + r) / 2;
		if (fun(mid) - y > 0)r = mid;
		else l = mid;
	}
	return r;
}
int main()
{
	int T;
	int y;
	while (cin>>T)
	{
		for (int i = 0; i < T; i++)
		{
			cin >> y;
			printf("%0.4f\n", ans(solve(y), y));
		}
	}
	return 0;
}

当然了,这个题目其实还是有一些特殊的。这是一个具有峰值的函数,我们要做的就是求出这个峰值,对于这种问题,其实我们有专门三分法就可以解决这个问题。三分的思想和二分是一样的,不过是在区间中多插入了一个点。通过比较这两个点的函数值,逐渐的缩小区间直到逼近峰值。这里只是简单的介绍思想,代码实现就不给出了。(因为我觉得还是二分+导数好用,嘿嘿)。

猜你喜欢

转载自blog.csdn.net/weixin_41863129/article/details/83116439