1. 程式人生 > >●Joyoi 收集郵票

●Joyoi 收集郵票

不變 現在 ret OS its 正向 target AC DC

題鏈:

http://www.joyoi.cn/problem/tyvj-2325
題解.1:

期望dp,(平方的期望不等於期望的平方。。。)
在這個題上坑了好久,也算是對期望的理解又深了一些。
很好的題解:http://www.cnblogs.com/ezyzy/p/6475861.html

再闡述一下平方的期望是在什麽情況下可以遞推的:
對於一個隨機變量x,我們知道其每個取值的概率,
那麽我們容易由定義得出這個隨機變量的期望E(x)=p1*x1+p2*x2+...,
以及這個隨機變量的平方的期望E(x²)=p1*x1²+p2*x2²+...。
現在由於種種原因,假設我們需要求出在這個隨機變量的每個取值都加1但是概率不變的情況下的新的平方的期望E‘(x²)=p1*(x1+1)²+p2*(x2+1)²+...,


(註意,只是權值改變,對應概率未變)
那麽這個時候就可以用平方的期望的遞推式子了:E‘(x²)=E(x²)+2*E(x)+1

反觀這類題目的dp轉移往往是分為當前狀態成功與否兩種情況,
而當我們確定了某種情況後,接下來就需要計算當前+後面的東西的總期望,再乘上這種情況的概率。
因為已確定了是成功還是失敗,所以當前狀態對期望的貢獻只是在隨機變量的取值上,而沒有影響到其概率分布,所以才可以直接使用平方的期望的遞推式子。


代碼.1:

#include<bits/stdc++.h>
#define MAXN 10005
using namespace std;
double g[MAXN],f[MAXN];
int N;
int main(){
	ios::sync_with_stdio(0);
	cin>>N;
	for(int i=N-1;i>=0;i--){
		f[i]=f[i+1]+1.0*N/(N-i);
		g[i]=1.0*i/N*(2*f[i]+1)+1.0*(N-i)/N*(g[i+1]+2*f[i+1]+1);
		g[i]=g[i]/(N-i)*N;
	}
	cout<<fixed<<setprecision(2)<<(g[0]+f[0])/2<<endl;
	return 0;
}

  

題解.2:

求期望。。。
正向枚舉已經收集了i個,並計算收集第i個時的相關信息與貢獻,
令a[i]表示收集了i個時期望購買了a次。
那麽a[i+1]=a[i]+N/(N-i) (加上收集第i+1個時期望的購買次數)
然後要求收集第i+1個時期望的花費,
首先之前已經期望購買了a次,那麽我們考慮:
首先一定要先買一次,價格為a+1
如果沒買到(概率為i/N),再買一次,價格為a+2
如果還沒買到(概率為(i/N)²),在買一次,價格為a+3
....(子子孫孫,無窮匱也。。。)
那麽可以列出期望花費的式子:令p=i/N
A=(a+1)+(a+2)*p+(a+3)*p²+(a+4)*p³+.... [1]式


然後我們要求A的值,用錯位相減法的得到,即:
A*p= (a+1)*p+(a+2)*p²+(a+3)*p³+.... [2]式
[1]式-[2]式:
(1-p)*A=a+1+p+p²+p³+...,是一個無窮項的等比數列
=a+1/(1-p)
所以得到A=(a+1/(1-p))/(1-p)
然後把A加進答案ans即可,(期望的線性可加性嘛,A即表示收集第i+1個所期望的花費)

代碼.2:

#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
double p,a,ANS;
int N;
int main(){
	ios::sync_with_stdio(0);
	cin>>N;
	for(int i=0;i<N;i++){
		ANS+=(a+1.0*N/(N-i))/(1-1.0*i/N);
		a+=1.0*N/(N-i);
	}
	cout<<fixed<<setprecision(2)<<ANS<<endl;
	return 0;
}

  

●Joyoi 收集郵票