1. 程式人生 > 實用技巧 >題解 SP1026 【FAVDICE - Favorite Dice】

題解 SP1026 【FAVDICE - Favorite Dice】

首先,這是一道經典的期望dp題

因為最終狀態 $ (所有面都被篩到過) $ 是確定的,所以才用 逆推 ,設狀態

$ f[i] $ 表示已經篩到了 $ i $ 個不同的面,有 $ i\over n $ 的概率是由$ f[i] $ 轉移而來的,

也就是篩到了之前篩過的面,有 $ {n-i\over n} $ 的概率是由 $ f[i+1] $
轉移得到的,

也就是呢,篩到了一個之前沒有篩到過的面,並且無論從哪裡來,這次的期望次數都

比原來的期望次數多 $ 1 $,所以就得到了轉移方程:

$ f[i] = {i \over n} \times f[i] + {n-i \over n} \times f[i+1] $;

注意把 $ f[i] $ 化簡到一邊;

另外,可以用滾動陣列的;

$ f[i]=f[i+1]+n/(n-i) $;

AC 程式碼

#include<iostream>
#include<cstdio>
using namespace std;
int n,T;
double g[2];
int main(){
	int i;
	scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		g[n&1]=0;
		i=n-1;
		for(;i>=0;i--) g[i&1]=1.0*g[(i+1)&1]+1.0*n/(n-i);
		printf("%0.2f\n",g[0]); 
	}
}