求最大圓錐體積(三分法求最值問題)

B君要用一個表面積爲S的圓錐將白山雲包起來。

B君希望包住的白山雲體積儘量大,B君想知道體積最大可以是多少。

注意圓錐的表面積包括底面和側面。
Input
一行一個整數,表示表面積S。(1 <= S <= 10^9)
Output
一行一個實數,表示體積。
Input示例
8
Output示例
1.504506

轉載於:http://www.cnblogs.com/vongang/archive/2012/10/30/2745988.html

二分法只適用與線性函數,當函數脫離線性而呈現凸性或者凹性的時候,三分是很有必要的。

三分過程如下圖

凸函數:

凹函數:



【感受】

          你還在爲求最值而推好幾頁的公式嗎?你還在爲求最值而推不出來結果而煩       惱嗎?吐舌頭沒有關係~!看了三分法的介紹,就知道求最值原來可以這麼簡單,就       運行一個生成樹的代碼就可以了,可憐我以前光推公式推半個多小時還不一定         對 大哭大哭,還是知道的東西太少啊,以後求最值問題不用推好幾頁了!


【代碼】

/* 三分法求最值*/
#include <iostream>
#include <cstdio>
#include  <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define eps 1e-9
#define pi 3.1415926
double maxV;
double Calc(double r, double s)
{
    double l = s / (pi * r) - r;
    if (l - r <= 0) return -1; //不成立
    double h = sqrt(l*l - r*r);
    double v = pi*r*r*h / 3.0;
    if (maxV < v)   maxV = v;  //必須在此取最大值!
    return v; //返回當前計算的體積
}

void three(double s) //三分法
{
    double Left, Right;
    double mid, midmid;
    double mid_value, midmid_value;
    Left = 0;
    Right = s;
    while (Left + eps < Right)
    {
        mid = (Left + Right) / 2;
        midmid = (mid + Right) / 2;
        mid_value = Calc(mid, s);
        midmid_value = Calc(midmid, s);
        // 假設求解最大極值.
        if (mid_value >= midmid_value)   Right = midmid;
        else    Left = mid;
    }
    printf("%.6f\n", maxV);
}
int main()
{
//#ifdef OFFLINE
//	freopen("t.txt", "r", stdin);
//#endif
    double s;
    while (~scanf("%lf", &s))
    {
        maxV = -inf; //初始化爲無窮小
        three(s);
    }
    return 0;
}

有問題留言~~~


發佈了54 篇原創文章 · 獲贊 43 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章