您的位置:首页 > 其它

HDU2899 Strange fuction

2016-02-29 21:16 302 查看
题意:求连续函数并且是凹函数的最小值

法一:‘

三分查找:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>

using namespace std;

double Y;

double ans(double x)
{
return 6*pow(x, 7) + 8*pow(x, 6) + 7*pow(x, 3) + 5*pow(x, 2) - Y*x;
}

int main()
{
//freopen("in.txt", "r", stdin);

int T;
double l, r, lmid, rmid;

cin>>T;

while(T--){
cin>>Y;
l = 0, r = 100;
while(fabs(l-r) > 1e-7){
lmid = (l + r)/2.0;
rmid = (r + lmid)/2.0;
if(ans(lmid) < ans(rmid)){
r = rmid;
}
else{
l = lmid;
}
}
printf("%.4f\n", ans(l));
}
}

0 ms飘过。第一次做三分搜索的题。

法二

由于求的是最小值,而且是连续函数,在极值点的导数值为0。

而且我猜测试数据的最小值一定出现在极小值点,而且在0<=x<=100一定有满足条件的极小值点。

好吧,我们来估计一下:

首先:0<Y<1e10,0<=x<=100,而导数为f'(x) = 42*x^6 + 48*x^5 + 21*x^2 + 10*x -Y;

明显 42*x^6 + 48*x^5 + 21*x^2 + 10*x 的取值在0与42*100^6之间,上限要大一些,但这已经远远大于1e10 了。

所以无论Y取何值,左边部分总存在比Y小和比Y大的,而且是连续函数,还是先小后大,所以一定会有极小值。

于是我们就可以愉快地用二分法了:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>

using namespace std;

double Y;

double der(double x)
{
return 42*pow(x, 6) + 48*pow(x, 5) + 21*pow(x, 2) + 10*x;
}

double ans(double x)
{
return 6*pow(x, 7) + 8*pow(x, 6) + 7*pow(x, 3) + 5*pow(x, 2) - Y*x;
}

int main()
{
// freopen("in.txt", "r", stdin);

int T;
double l, r, mid;

cin>>T;

while(T--){
cin>>Y;
l = 0, r = 100;
while(fabs(der(mid) - Y) > 1e-7){

mid = (l + r)/2;

if(der(mid) > Y){
r = mid;
}
else{
l = mid;
}
}
printf("%.4f\n", ans(mid));
}
}
但是15 ms 压过。好吧慢一些,而且证明很蛋疼,虽然写的时候根本没想那么多,写博客才突然想起来,高中数学不好。。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: