P1850 換教室 期望DP

2022-03-16 14:34:44 字數 3698 閱讀 4933

對於剛上大學的牛牛來說,他面臨的第乙個問題是如何根據實際情況申請合適的課程。

在可以選擇的課程中,有 2n2n2n 節課程安排在 nnn 個時間段上。在第 iii(1≤i≤n1 \leq i \leq n1≤i≤n)個時間段上,兩節內容相同的課程同時在不同的地點進行,其中,牛牛預先被安排在教室 cic_ici​上課,而另一節課程在教室 did_idi​進行。

在不提交任何申請的情況下,學生們需要按時間段的順序依次完成所有的 nnn 節安排好的課程。如果學生想更換第 iii 節課程的教室,則需要提出申請。若申請通過,學生就可以在第 iii 個時間段去教室 did_idi​上課,否則仍然在教室 cic_ici​上課。

由於更換教室的需求太多,申請不一定能獲得通過。通過計算,牛牛發現申請更換第 iii 節課程的教室時,申請被通過的概率是乙個已知的實數 kik_iki​,並且對於不同課程的申請,被通過的概率是互相獨立的。

學校規定,所有的申請只能在學期開始前一次性提交,並且每個人只能選擇至多 mmm 節課程進行申請。這意味著牛牛必須一次性決定是否申請更換每節課的教室,而不能根據某些課程的申請結果來決定其他課程是否申請;牛牛可以申請自己最希望更換教室的 mmm 門課程,也可以不用完這 mmm 個申請的機會,甚至可以一門課程都不申請。

因為不同的課程可能會被安排在不同的教室進行,所以牛牛需要利用課間時間從一間教室趕到另一間教室。

牛牛所在的大學有 vvv 個教室,有 eee 條道路。每條道路連線兩間教室,並且是可以雙向通行的。由於道路的長度和擁堵程度不同,通過不同的道路耗費的體力可能會有所不同。 當第 iii(1≤i≤n−11 \leq i \leq n-11≤i≤n−1)節課結束後,牛牛就會從這節課的教室出發,選擇一條耗費體力最少的路徑前往下一節課的教室。

現在牛牛想知道,申請哪幾門課程可以使他因在教室間移動耗費的體力值的總和的期望值最小,請你幫他求出這個最小值。

第一行四個整數 n,m,v,en,m,v,en,m,v,e。nnn 表示這個學期內的時間段的數量;mmm 表示牛牛最多可以申請更換多少節課程的教室;vvv 表示牛牛學校裡教室的數量;eee表示牛牛的學校裡道路的數量。

第二行 nnn 個正整數,第 iii(1≤i≤n1 \leq i \leq n1≤i≤n)個正整數表示 cic_ici​,即第 iii 個時間段牛牛被安排上課的教室;保證 1≤ci≤v1 \le c_i \le v1≤ci​≤v。

第三行 nnn 個正整數,第 iii(1≤i≤n1 \leq i \leq n1≤i≤n)個正整數表示 did_idi​,即第 iii 個時間段另一間上同樣課程的教室;保證 1≤di≤v1 \le d_i \le v1≤di​≤v。

第四行 nnn 個實數,第 iii(1≤i≤n1 \leq i \leq n1≤i≤n)個實數表示 kik_iki​,即牛牛申請在第 iii 個時間段更換教室獲得通過的概率。保證 0≤ki≤10 \le k_i \le 10≤ki​≤1。

接下來 eee 行,每行三個正整數 aj,bj,wja_j, b_j, w_jaj​,bj​,wj​,表示有一條雙向道路連線教室 aj,bja_j, b_jaj​,bj​,通過這條道路需要耗費的體力值是 wjw_jwj​;保證 1≤aj,bj≤v1 \le a_j, b_j \le v1≤aj​,bj​≤v, 1≤wj≤1001 \le w_j \le 1001≤wj​≤100。

保證 1≤n≤20001 \leq n \leq 20001≤n≤2000,0≤m≤20000 \leq m \leq 20000≤m≤2000,1≤v≤3001 \leq v \leq 3001≤v≤300,0≤e≤900000 \leq e \leq 900000≤e≤90000。

保證通過學校裡的道路,從任何一間教室出發,都能到達其他所有的教室。

保證輸入的實數最多包含 333 位小數。

輸出一行,包含乙個實數,四捨五入精確到小數點後恰好222位,表示答案。你的輸出必須和標準輸出完全一樣才算正確。

測試資料保證四捨五入後的答案和準確答案的差的絕對值不大於 4×10−34 \times 10^4×10−3。 (如果你不知道什麼是浮點誤差,這段話可以理解為:對於大多數的演算法,你可以正常地使用浮點數型別而不用對它進行特殊的處理)

輸入 #1複製

3 2 3 3

2 1 2

1 2 1

0.8 0.2 0.5

1 2 5

1 3 3

2 3 1

輸出 #1複製

2.80
【樣例1說明】

所有可行的申請方案和期望收益如下表:

【提示】

道路中可能會有多條雙向道路連線相同的兩間教室。 也有可能有道路兩端連線的是同一間教室。

請注意區分n,m,v,e的意義, n不是教室的數量, m不是道路的數量。

特殊性質1:圖上任意兩點 aia_iai​, bib_ibi​, aia_iai​≠ bib_ibi​間,存在一條耗費體力最少的路徑只包含一條道路。

特殊性質2:對於所有的 1≤i≤n1≤ i≤ n1≤i≤n, ki=1k_i= 1ki​=1 。

dp[i][j][k] 表示第i節課換了j次,上一次換還是沒換(k=0,1)最小的期望值;

我們根據上節課換沒換推出上節課的位置和現在的位置;

最短路不用說;

因為是期望,所以每次你要乘上成功和不成功的概率;

如果沒換就直接加;

#include#include

#include

using

namespace

std;

typedef

long

long

ll;const

int maxn=2010

;const

double inf=1e9+10

;int

n,m,v,e;

int g[310][310

];int dis[310][310

];int

c[maxn],d[maxn];

double

k[maxn];

double dp[maxn][maxn][2

];int

main()

for(int kq=1;kq<=v;kq++) for(int i=1;i<=v;i++) for(int j=1;j<=v;j++)

for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) for(int k=0;k<=1;k++)

dp[i][j][k]=inf;

for(int i=1;i<=v;i++) dis[i][i]=dis[i][0]=dis[0][i]=0

; dp[

1][0][0]=0;dp[1][1][1]=0

;

for(int i=2;i<=n;i++)

}double ans=inf;

for(int i=0;i<=m;i++) ans=min(ans,min(dp[n][i][0],dp[n][i][1

]));

printf(

"%.2lf

",ans);

return0;

}

double不要用memset,賦值是小數點後面的數

P1850 換教室 dp 期望

流下了不會概率的眼淚,由於不會概率,轉移少寫了點東西。這個dp很簡單,就是乙個普通的線性dp加點期望。剛開始寫這道題時信筆寫下 dp 0 1 i j 表示到第 i 個時間段時,已經申請了換 j 門課程的教室,當前申請0不換 1換教室的最小數學期望。注意,我們的狀態定義是申請,而不是已經申請成功,這樣...

洛谷 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...