題鏈:
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; }