流下了不會概率的眼淚,由於不會概率,轉移少寫了點東西。。。
這個dp很簡單,就是乙個普通的線性dp加點期望。(剛開始寫這道題時信筆寫下)\(dp[0/1][i][j]\)表示到第\(i\)個時間段時,已經申請了換\(j\)門課程的教室,當前申請0不換、1換教室的最小數學期望。
注意,我們的狀態定義是申請,而不是已經申請成功,這樣定義狀態就可以統計出數學期望了。
對於當前狀態沒申請的情況,如果上乙個時間段也沒申請,那只有一種可能性發生,即倆狀態都沒換;如果上乙個時間段申請了,那上乙個狀態就可能沒成功,也可能成功了,二者我們都要統計。
對於申請了的情況也是一樣的。
故有轉移(巨長版)
\[dp[0][i][j]=min(dp[0][i-1][j]+dist(c_,c_),\\dp[1][i-1][j]+k_*dist(d_,c_i)+(1-k_)*dist(c_,c_i))\\~\\dp[1][i][j]=min(dp[0][i-1][j-1]+k_i*dist(c_,d_i)+(1-k_i)*dis(c_,c_i),\\dp[1][i-1][j-1]+k_*k_i*dist(d_,d_i)+(1-k_)*k_i*dist(c_,d_i)+k_*(1-k_i)*dist(d_,c_i)+(1-k_)*(1-k_i)*dist(c_,c_i))
\]其中\(dist(x,y)\)表示最短路,觀察資料範圍,點數較少,直接上floyd。
初始化\(dp[0][1][0]=dp[1][1][1]=0,dp[0/1]=inf\)
答案在\(min(dp[0/1][n][0\sim m])\)。
注意重邊和i\(inf\) 的設定,不要搞混\(n\)和\(v\)。
#include#include#include#include#include#include#include#include#include#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define n 310
#define m 2010
#define mod 2520
#define e 1e-12
#define eps 4e-4
#define re register
using namespace std;
inline int read()
while(c>='0'&&c<='9')
return x*f;
}int n,m,v,e,c[m],d[m],dis[n][n];
double k[m],dp[2][m][m];
inline int min(int a,int b)
double ans=inf*1.0;
for(re int i=0;i<=m;++i)
ans=dmin(ans,dmin(dp[0][n][i],dp[1][n][i]));
printf("%.2lf",ans);
return 0;
}
P1850 換教室 期望DP
對於剛上大學的牛牛來說,他面臨的第乙個問題是如何根據實際情況申請合適的課程。在可以選擇的課程中,有 2n2n2n 節課程安排在 nnn 個時間段上。在第 iii 1 i n1 leq i leq n1 i n 個時間段上,兩節內容相同的課程同時在不同的地點進行,其中,牛牛預先被安排在教室 cic i...
洛谷 P1850 換教室(期望dp)
用dp i j 0 1 表示到第i節課 申請了j次,第i節課是否申請的最小體力和。然後分別從dp i 1 j 0 dp i 1 j 1 dp i 1 j 1 0 dp i 1 j 1 1 瘋狂轉移過來。先跑一邊floyd求最短路。注意double無法用memset初始化。具體看 吧。比較易懂。1 i...
P1850 換教室 概率dp
其實說是概率dp,本質上和dp沒什麼區別,就是把所有可能轉移的情況全列舉一下就行了,不過dp方程確實有點長。ps 這個題的floyed我竟然之前寫跪了。題目 題目描述 對於剛上大學的牛牛來說,他面臨的第乙個問題是如何根據實際情況申請合適的課程。在可以選擇的課程中,有 2n2n2n 節課程安排在 nn...