codeforces 185B - Mushroom Scientists ( 三分搜索)

题意: 四个数 s  a b c 均为非负 ,求x,y,z  使得x ^a  * y^ b* z^c  值最大 其中 s>=x+y+z

这个题用拉格朗日函数可以证明  一个结论

在 s= x + y +z 时 x=s/(a+b+c) ,y=s/(a+b+c) ,z=s/(a+b+c) 最大

x ^a  * y^ b* z^c  的值最大

证明很关键啊,翻了高数 课本搞弄明白,伤不起啊

据某大牛说 可以用 三分搜索 搞定,但是 由于精度卡死 了 不少孩纸 。。。

你妹,精度小了,WA ,精度大了,居然卡 边界值  程序和死循环似的

幸运的是那时自己还不会,没有被恶心-->__<--

处理时 循环加有限的的限定

三个数 确定两个 即可 所以  二重三分搜索搞定,感谢某大牛的代码

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double  EPS = 0.0000000000001;

int s, a, b, c;
inline double max2(double  s, bool flag = false)
{
    double  l = 0, r = s;
    int k=100;
    while(k--)
    {
        double  d = (r - l) / 3;
        double  ml = l + d;
        double  mr = r - d;
        if(b*log(ml) + c*log(s - ml) > b*log(mr) + c*log(s - mr))
            r = mr;
        else
            l = ml;
    }
    if(flag)
        printf("%0.10f %0.10f\n", double(l), double(s - l));
    return b*log(l) + c*log(s - l);
}
inline void max1()
{
    double  l = 0, r = s;
    int k=100;
    while(k--)
    {
        double  d = (r - l) / 3;
        double  ml = l + d;
        double  mr = r - d;
        if(max2(s - ml) + a*log(ml) > max2(s - mr) + a*log(mr))
            r = mr;
        else
            l = ml;
    }
    printf("%0.10f ", (double)l);
    max2(s - l, true);
}
int main()
{
    cin >> s >> a >> b >> c;
    max1();
    return 0;
}

 

 

 

你可能感兴趣的:(codeforces)