模拟退火 BZOJ-2428
来源:互联网 发布:表情包软件下载 编辑:程序博客网 时间:2024/06/16 02:51
大家都很强,可与之共勉。
Link
题解
首先随机设定每个元素所在的组,然后求出初始的方差,然后开始退火,每次退火时首先随机选一个元素t,并得到它所在的组x,然后需要选一组y,把t放入组y中,选这个组y也要讲究技巧,若温度高的话,此时状态不稳定,很难使最终的搜索结果尽量更优,那么就需要贪心地选当前元素值之和最小的组。若温度低的话,此时状态比较稳定,而且各个组的元素和基本上差不多,此时就需要随机选个y,然后尝试将t放入组y中,若新解更优,则把旧解更新为新解,否则在[0,10000)随机一个数,若随机的数比T小,那么就把旧解更新为新解(T越小,在这种情况下更新解的概率也就越小,T的大小相当于是解的可靠性,T越小,说明此时解越可靠,在新解并不优的情况下改变原有解的概率也就越小),否则保持原有的解不变。
真-模拟退火
/************************************************************** Problem: 2428 User: Lazer2001 Language: C++ Result: Accepted Time:6396 ms Memory:1304 kb****************************************************************/# include <bits/stdc++.h>int n, m ;double ave, sum [25] ;int place [25], a [25] ;inline double smin ( double& d, const double& x ) { x < d ? d = x : 0 ;}inline double SA ( ) { double ans ( 0 ) ; for ( int i = 1 ; i <= n ; ++ i ) place [i] = rand ( ) % m + 1 ; for ( int i = 1 ; i <= m ; ++ i ) sum [i] = 0 ; for ( int i = 1 ; i <= n ; ++ i ) sum [place [i]] += a [i] ; for ( int i = 1 ; i <= m ; ++ i ) ans += ( sum [i] - ave ) * ( sum [i] - ave ) ; register double temprature = 10000.0 ; while ( temprature > 1e-8 ) { temprature *= 0.98 ; int t ( rand ( ) % n + 1 ), x ( place [t] ), y ; if ( temprature > 500 ) { y = std :: min_element ( sum + 1, sum + 1 + m ) - sum ; } else { y = rand ( ) % m + 1 ; } if ( x ^ y ) { double tmp ( ans ) ; tmp -= ( sum [x] - ave ) * ( sum [x] - ave ) ; tmp -= ( sum [y] - ave ) * ( sum [y] - ave ) ; sum [x] -= a [t], sum [y] += a [t] ; tmp += ( sum [x] - ave ) * ( sum [x] - ave ) ; tmp += ( sum [y] - ave ) * ( sum [y] - ave ) ; if ( tmp <= ans ) { ans = tmp ; place [t] = y ; continue ; } if ( ( rand ( ) % 1000 ) > temprature ) { sum [x] += a [t], sum [y] -= a [t] ; } else { ans = tmp ; place [t] = y ; } } } return ans ;} int main ( ) { srand ( 20010608 ) ; scanf ( "%d%d", & n, & m ) ; sum [0] = 0x3f3f3f3f ; double ans ( 0x3f3f3f3f ) ; for ( int i = 1 ; i <= n ; ++ i ) scanf ( "%d", a + i ) ; for ( int i = 1 ; i <= n ; ++ i ) ave += a [i] ; ave /= ( 1.0 * m ) ; for ( register int i = 1 ; i <= 5000 ; ++ i ) smin ( ans, SA ( ) ) ; return printf ( "%.2lf\n", sqrt ( ans / ( 1.0 * m ) ) ), 0 ; }
阅读全文
0 0
- 模拟退火 BZOJ-2428
- bzoj:2428: [HAOI2006]均分数据 模拟退火
- BZOJ 2428 [HAOI2006]均分数据 模拟退火
- BZOJ 2428: [HAOI2006]均分数据 模拟退火
- BZOJ 2428 模拟退火 解题报告
- bzoj 2428 均分数据 模拟退火
- BZOJ 3680 模拟退火
- BZOJ 3680 模拟退火
- BZOJ 1379 模拟退火
- 模拟退火 BZOJ-3680
- [BZOJ 2428][HAOI 2006]均分数据(模拟退火)
- bzoj 2428: [HAOI2006]均分数据 (模拟退火)
- 【BZOJ】【P3680】【吊打XXX】【题解】【模拟退火】
- BZOJ 3680 吊打XXX 模拟退火
- 模拟退火(bzoj 3680: 吊打XXX)
- bzoj 3680 吊打xxx 模拟退火
- BZOJ 2210: Pku1379 Run Away 模拟退火
- 【BZOJ】【P1038】【ZJOI2008】【瞭望塔】【题解】【二分+模拟退火】
- 桌面闪屏处理(可能的原因)
- Java基础部分第五节
- 深入php-fpm的两种进程管理模式详解
- day01_基础加强
- 面试题之MySQL多表查询方法
- 模拟退火 BZOJ-2428
- IDEA十大快捷键(for、System.out、main等)
- 两篇word文档行间距设置的一样但是显示的不一样的解决方法
- MVC WebApi自定义拦截器
- Android自定义view保存状态学习总结
- 获取包名类名
- MySQL 高可用:mysql+mycat实现数据库分片(分库分表)
- 错误集
- Echarts请求json数据实例