1. 程式人生 > >二分法求最值(HDU2899)

二分法求最值(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;
}

當然了,這個題目其實還是有一些特殊的。這是一個具有峰值的函式,我們要做的就是求出這個峰值,對於這種問題,其實我們有專門三分法就可以解決這個問題。三分的思想和二分是一樣的,不過是在區間中多插入了一個點。通過比較這兩個點的函式值,逐漸的縮小區間直到逼近峰值。這裡只是簡單的介紹思想,程式碼實現就不給出了。(因為我覺得還是二分+導數好用,嘿嘿)。