BZOJ 3680: 吊打XXX (模拟退火)

//yy:今天简单入门学了下ORZ

爬山算法:兔子朝着比现在高的地方跳去。它找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是爬山算法,它不能保证局部最优值就是全局最优值。

模拟退火:兔子喝醉了。它随机地跳了很长时间。这期间,它可能走向高处,也可能踏入平地。但是,它渐渐清醒了并朝最高方向跳去。这就是模拟退火。

题目链接:BZOJ 3680: 吊打XXX

1<=n<=10000,-100000<=xi,yi<=100000

题意:找一个点\alpha ,使得\sum_{i=1}^{N}{dist(\alpha ,i) * W_{i} } 最小

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <climits>
 6 #include <cstdlib>
 7 #define FIRE(x) (x *= 0.98)
 8 using namespace std;
 9 typedef long long ll;
10 const int N = 10005;
11 const double inf = 1e17;
12 const double PI = acos(-1.0);
13 const double eps = 1e-3;
14 struct Point{
15     double x, y, w;
16     Point(){}
17     Point(double _x, double _y):x(_x), y(_y) {}
18     Point operator -(const Point &b)const{
19         return Point(x - b.x,y - b.y);
20     }
21     double operator *(const Point &b)const{
22         return x*b.x + y*b.y;
23     }
24 }now, ans, po[N];
25 double dist(Point a, Point b) {return sqrt((a-b)*(a-b));}
26 int n;
27 double tot = inf;
28 double statistic(Point p) {
29     double res = 0.0;
30     for(int i = 0; i < n; ++i) res += dist(p, po[i]) * po[i].w;
31     if(res < tot) tot = res, ans = p;
32     return res;
33 }
34 double Rand() {return (rand()%1000 + 1) / 1000.0;}
35 void SA(double T) {
36     double alpha, sub;
37     while(T > eps) {
38         alpha = 2.0 * PI * Rand();
39         Point t(now.x + T * cos(alpha), now.y + T * sin(alpha));
40         sub = statistic(now) - statistic(t);
41         if(sub >= 0 || exp(sub / T) >= Rand()) now = t;
42         FIRE(T);
43     }
44     T = 0.001;
45     for(int i = 1; i <= 1000; ++i) {
46         alpha = 2.0 * PI * Rand();
47         Point t(ans.x + T * cos(alpha) * Rand(), ans.y + T * sin(alpha) * Rand());
48         statistic(t);
49     }
50 }
51 int main(){
52     srand(123456);
53     scanf("%d", &n);
54     for(int i = 0; i < n; ++i) {
55         scanf("%lf%lf%lf", &po[i].x, &po[i].y, &po[i].w);
56         now.x += po[i].x;   now.y += po[i].y;
57     }
58     now.x /= n; now.y /= n;
59     double T = 1000.0;
60     SA(T);
61     printf("%.3f %.3f\n", ans.x, ans.y);
62     return 0;
63 }
View Code

 

posted @ 2017-07-27 21:51  GraceSkyer  阅读(362)  评论(0编辑  收藏  举报

~~~~~~ACM大牛语录,激励一下~~~~~~

为了世界的和平,为了女生的安全,我拼命做题,做题,做题!

用最短的时间,刷最多的题!

给我一滴泪,我就看到了你全部的海洋!

seize the hour, seize the day.

人生难免有无奈,幸福走远了,或是感叹幸福来迟了.其实我一直相信,无论手中的幸福是多么微不足道的感觉,我会把握住那每一分,每一秒,当幸福依旧像那百鸟般飞逝,终究无法掌握时,我会感谢它,曾经降临过!

A自己的题,让别人郁闷去吧

WA肠中过,AC心中留 TLE耳边过,AC特别牛

天然的悲苦和伤逝,过去有过,以后还会有

^*^一步一步往上爬^*^

AC就像练级,比赛就像PK. 练级不如PK好玩

其实,世上本没有ACM,AC的人多了,也便有了!

AC无止尽~ Seek you forever~

找呀找呀找水题,找到一个AC一个呀!

AC是检验程序的唯一标准。

真的猛士,敢于直面惨淡的人生,敢于正视淋漓的鲜血……