調了一下午qaq…讓我對數學期望的理解又提公升了乙個層次。
首先,我們發現
v<=3
00, 這樣我們就可以用 fl
oyd 演算法來 o(
n3) 處理出任意兩點間的最短路。
對於題目,我們不難列出狀態dp
[i][
j][0
/1]。
這個狀態代表:走到第
i個點,用了
j次機會,當前使用了(0表示未使用,1表示使用)機會的最小期望值。
首先,我們考慮dp
[i][
j][0
]dp[
i][j
][0]
=dp[
i−1]
[j][
0]+f
[ci−
1][
ci]
dp[i][j
][0]
=dp[
i−1]
[j][
1]+f
[ci−
1][
ci]
∗(1−
k[i−
1])+
f[di
−1]
[ci
]∗k[
i−1]
體會一下,上一次使用機會的話會面臨兩種情況:
1.交換成功,路程為f[
di−1
][c
i],概率為k[
i−1]
.2.未交換成功,路程為f[
ci−1
][c
i],概率為1−
k[i−
1].再考慮一下當前使用機會,分6種情況。
1.上一輪未交換,當前交換失敗:路程為f[
ci−1
][c
i],概率為1−
k[i]
2.上一輪未交換,當前交換成功:路程為f[
ci−1
][d
i],概率為k[
i]3.上一輪交換失敗,當前交換失敗,路程為f[
ci−1
][c
i],概率為(1
−k[i
−1])
∗(1−
k[i]
)4.上一輪交換失敗,當前交換成功,路程為f[
ci−1
][d
i],概率為(1
−k[i
−1])
∗k[i
]5.上一輪交換成功,當前交換失敗,路程為f[
di−1
][c
i],概率為k[
i−1]
∗(1−
k[i]
)6.上一輪交換成功,當前交換成功,路程為f[
di−1
][d
i],概率為k[
i−1]
∗k[i
]最後將所有資訊合併即可,另外細節巨多,到注意初始化。
code:
#include
#include
#include
using namespace std;
const
int maxn =
350;
const
int n =
2000+5
;const
double inf =
1000000000
;int f[maxn]
[maxn]
, c[n]
, d[n]
, n,m,v,e;
double k[n]
, dp[n]
[n][2]
;inline
void
update
(double
&a,double b)
intmain()
for(
int i =
0;i <= v;
++i) f[i][0
]= f[0]
[i]= f[i]
[i]=0;
for(
int k =
1;k <= v;
++k)
for(
int i =
1;i <= v;
++i)
for(
int j =
1;j <= v;
++j)
if(f[i]
[k]!= inf && f[k]
[j]!= inf)f[i]
[j]=
min(f[i]
[j], f[i]
[k]+ f[k]
[j])
;for
(int i =
0; i <= n;
++i)
for(
int j =
0; j <= m;
++j)dp[i]
[j][0]
= dp[i]
[j][1]
= inf;
dp[1]
[0][
0]= dp[1]
[1][
1]= dp[0]
[0][
0]=0
;for
(int i =
1;i <= n;
++i)}}
double ans = inf;
for(
int j =
0;j <= m;
++j)
printf
("%.2f"
,ans)
;return0;
}
P1850 換教室 數學期望,dp,Floyd
一張圖,n nn次,每次在c ic i ci 上課,可以申請換課室到d id i di 成功概率k ik i ki 求最短需要走的路徑的期望長度 先f lo dy flody flod y預處理多源最短路,然後考慮dpdp dp設fi,j,0 1f fi,j,0 1 表示前i ii次,已經申請了j ...
洛谷 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。一般看見這種題就想暴力了,看一下資料範圍,暴力應該還是挺好想的吧。24分注意到有6個測試點m 0m 0,則說明不能提出申請,那麼只需要求出全圖的兩兩之間的最短路,路徑唯一確定。52分注意到另外有7個測試點m 1m 1,只能提出一次申請。我們可以直接列舉在 提出申請...