正确方法是模拟退火?
根据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 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen