打模拟题打得心累...丧病题毁我青春...然后无聊就看了看最近被提的很多的蒙特卡洛方法...
什么是蒙特卡洛
怎么说呢...因为没有接触到蒙特卡洛牛逼的应用,所以对它的理解还不是非常深刻...
蒙特卡洛的核心是随机...如果一个问题可以转化为一些类型的期望或随机那么似乎就可以用蒙特卡洛------>蒙特卡洛是一种思想而不是什么特定算法...貌似可以这么理解.比如我们要求一个不规则图形的面积,那么我们随机撒豆子然后数出图形内的豆子数除以总豆子数乘上平面的面积. 非常巧妙地运用概率.
更加学术的介绍可以上wikipad----太学术以至于并不怎么想看...
简单的一个实现
对于蒙特卡洛的一个简单应用,即求pi的大小.这么一个非常抽象的数放到图像上就变成了圆的面积与正方形之比.然后我们随机生成点就能粗略计算pi的大小
/*========================================================================== # Last modified: 2016-03-14 11:46 # Filename: pi.cpp # Description: ==========================================================================*/ #define me AcrossTheSky #include <cstdio> #include <cmath> #include <ctime> #include <string> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <set> #include <map> #include <stack> #include <queue> #include <vector> #define lowbit(x) (x)&(-x) #define FOR(i,a,b) for((i)=(a);(i)<=(b);(i)++) #define FORP(i,a,b) for(int i=(a);i<=(b);i++) #define FORM(i,a,b) for(int i=(a);i>=(b);i--) #define ls(a,b) (((a)+(b)) << 1) #define rs(a,b) (((a)+(b)) >> 1) #define getlc(a) ch[(a)][0] #define getrc(a) ch[(a)][1] #define maxn 100000 #define maxm 100000 #define pi 3.1415926535898 #define _e 2.718281828459 #define INF 1070000000 using namespace std; typedef long long ll; typedef unsigned long long ull; /*==================split line==================*/ int main(){ srand(time(0)); int cnt=0; ll n=1000000000; FORP(i,1,n) { double x=rand()%1000,y=rand()%1000; x/=1000.0,y/=1000.0; if (sqrt(x*x+y*y)<=1) cnt++; } printf("%lf",(double)cnt/n*4); }
实现得非常草率....
然后我们发现它的精度不太好,wikipad说10^9个点能达到前4位,差不多吧...计算机的rand貌似只是伪随机数?
蒙特卡洛在OI中的运用
并没有遇到过...哈哈哈哈哈感觉这个标题非常逗...以后碰到再补上好了...