hdu 2899 Strange fuction 三分

缘起

继续学习三分~ hdu 2899 Strange fuction

分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
给定如下函数
F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100)
求最小值。

【输入】
多样例, 每个样例包含一个实数

【输出】
最小值

【样例输入】
2
100
200

【样例输出】
-74.4291
-178.8534

【限制】
1s

套三分板子即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//#include "stdafx.h"
#include <stdio.h>
#include <math.h>
//#define LOCAL

const double eps = 1e-8;
inline double f(double x, double y)
{
return 6 * pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*pow(x,2)-y*x; // 就不快速幂了哈
}

double y;

int main()
{
#ifdef LOCAL
freopen("d:\\data.in", "r", stdin);
// freopen("d:\\my.out", "w", stdout);
#endif
int kase;
scanf("%d", &kase);
while(kase--)
{
scanf("%lf", &y);
double lo =0, hi = 100, lmid, rmid, ans;
while(hi>lo+eps)
{
lmid = lo+(hi-lo)/3, rmid = hi-(hi-lo)/3;
if (f(lmid, y)<f(rmid, y))
{
ans = rmid;
hi = rmid;
}
else
{
ans = lmid;
lo = lmid;
}
}
printf("%.4lf\n", f(ans, y));
}
return 0;
}

ac情况

Status Accepted
Memory 1244kB
Length 685
Lang G++
Submitted 2019-09-27 14:54:36
Shared
RemoteRunId 30734912

当然,本题还可以用模拟退火来做.(因为属于大搜索空间不能暴力枚举的那种)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//#include "stdafx.h"
#include <stdio.h>
#include <math.h>
//#define LOCAL

double ans, y, eps = 1e-8, cur, nxt;
int dir[2] = {-1,1};

inline double f(double x, double y)
{
return 6 * pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*pow(x,2)-y*x;
}

void sa() // 模拟退火
{
double step = 50; // 初始步长
cur = 0, ans = f(cur, y); // 出发点
while(step>eps)
{
bool ok = true;
while(ok)
{
ok = false;
for (int i = 0; i<2; i++)
{
nxt = cur+dir[i]*step;
if (nxt+eps>0 && nxt<100+eps) // 如果nxt>=0 && nxt<=100, 则它就是合法的状态
{
double nxte = f(nxt, y);
if (ans>nxte+eps)
{
ans = nxte; // 优化ans
cur = nxt; // 状态转移
ok = true;
}
}
}
}
step/=2;
}
}

int main()
{
#ifdef LOCAL
freopen("d:\\data.in", "r", stdin);
// freopen("d:\\my.out", "w", stdout);
#endif
int kase;
scanf("%d", &kase);
while(kase--)
{
scanf("%lf", &y);
sa();
printf("%.4lf\n", ans);
}
return 0;
}

ac情况

Status Accepted
Memory 1240kB
Length 917
Lang G++
Submitted 2019-09-27 22:42:46
Shared
RemoteRunId 30742146