正确方法是模拟退火?

根据wulala的讲法,我们多random_shuffle几发,对序列贪心一下就好了

反正都是随机化的做法,能过就行2333

 

 1 /**************************************************************
 2     Problem: 2428
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:3356 ms
 7     Memory:816 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cmath>
12 #include <algorithm>
13  
14 using namespace std;
15 typedef double lf;
16 const int N = 25;
17  
18 int n, m;
19 lf mid, ans;
20 int a[N], p[N];
21  
22 inline lf sqr(lf x) {
23     return x * x;
24 }
25  
26 inline lf work() {
27     int cnt = 1, sum = 0, i;
28     lf tmp = 0, t1, t2;
29     for (i = 1; i <= n && cnt < m; ++i)
30         if (sum + a[p[i]] >= mid) {
31             t1 = sqr(sum - mid), t2 = sqr(sum + a[p[i]] - mid);
32             if (t1 < t2) tmp += t1, sum = a[p[i]];
33             else tmp += t2, sum = 0;
34             ++cnt;
35         } else sum += a[p[i]];
36     while (i <= n) sum += a[p[i++]];
37     tmp += sqr(sum - mid);
38     return tmp;
39 }
40  
41 int main() {
42     int i;
43     scanf("%d%d", &n, &m);
44     for (i = 1; i <= n; ++i) {
45         p[i] = i;
46         scanf("%d", a + i);
47         mid += a[i];
48     }
49     mid /= m, ans = 1e60;
50     for (i = 1; i <= 500000; ++i) {
51         random_shuffle(p + 1, p + n + 1);
52         ans = min(ans, work());
53     }
54     printf("%.2lf\n", sqrt(ans / m));
55     return 0;
56 }
View Code

 

posted on 2015-03-09 22:19  Xs酱~  阅读(748)  评论(0编辑  收藏  举报