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;
}
Just a little, maybe change the world