hihocoder 1164 随机斐波那契 (期望dp)

其实最简单的暴力O(n^3)是能过的,,这里主要是提一下对于大数据时怎么处理。

对于某个n来说我们要求a_n的期望,考虑一下我们求a_n的时候是随机从a_n前面的n项中抽出两项然后相加得到a_n,那么我们把所有情况分为两类:第一类是所选的两个数中有a_(n-1),第二类是所选的数中没有a_(n-1)。然后分别把两类的期望求出来相加就好了。

对于第一类的期望:它就是从a_0加到a_(n-1)的和再加上n个a_(n-1)(因为每个数都需要a_(n-1)去跟它配对)然后要乘以第一类的概率就是n/(n*n)=1/n。

对于第二类的期望:我们要知道a_(n-1)是一个期望,期望的意思就相当于我们从前面(n-1)个数中随便选取两个数的和是都可以用期望来代替的,那么我们只要再乘以随便选取两个数的概率(n-1)*(n-1)/(n*n)就好了。

#pragma warning(disable:4996)
#include <cstdio>
using namespace std;

double a[505];

int main(){
	a[0] = 1; a[1] = 2, a[2] = 3;
	for (int i = 3; i <= 500; i++){
		//这里我们可以边循环边处理处sum为前n项和就得到了O(n)的算法
		a[i] = a[i - 1] * (i - 1)*(i - 1);
		int cnt = i;
		double sum = 0;
		for (int j = 0; j < i; j++){
			sum += a[j] + a[i - 1];
		}
		sum *= 2;
		sum -= 2 * a[i - 1];
		a[i] += sum;
		a[i] /= (cnt*cnt);
	}
	int n;
	while (~scanf("%d", &n)){
		printf("%.6lf\n", a[n]);
	}
	return 0;
}
然后据说题解很牛X,(打表之前)我是绝对不会看出规律来的。O(∩_∩)O哈哈~

你可能感兴趣的:(hihocoder 1164 随机斐波那契 (期望dp))