NOIP2016 換教室 題解(奇怪的三種狀態)

2022-05-10 06:42:12 字數 3937 閱讀 6430

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

在可以選擇的課程中,有2n節課程安排在n個時間段上。在第i(1在不提交任何申請的情況下,學生們需要按時間段的順序依次完成所有的n節安排好的課程。如果學生想更換第i節課程的教室,則需要提出申請。若申請通過,學生就可以在第i個時間段去教室di上課,否則仍然在教室ci上課。

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

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

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

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

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

從檔案中讀入資料。

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

第二行n個正整數,第i(1<=i<=n)個正整數表示ci,即第i個時間段牛牛被安排上課的教室;保證1<=ci<=v.

第三行n個正整數,第i(1<=i<=n)個正整數表示di,即第i個時間段另一間上同樣課程的教室;保證1=第四行n個實數,第i(1<=i<=n)個實數表示ki,即牛牛申請在第i個時間段更換教室獲得通過的概率。保證0<=ki<=1。

接下來e行,每行三個正整數aj,bj,wj,表示有一條雙向道路連線教室aj,bj,通過這條道路需要耗費的體力值是wj;保證1<=aj,bj<=v,  1<=wj<=1000

保證1<=n<=2000,0<=m<=2000,1<=v<=300,0<=e<=90000。

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

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

輸出到檔案中。

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

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

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

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

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

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

這道題當時以為又是乙個大坑,先放著沒做。最近填坑時搞掉了,發現真容易。

不知道為啥,很多人都寫兩種狀態,就我寫了三種狀態,(其實本質一樣)於是調乙個小坑調了半天。

首先基本是所有人都會去想的,狀態為當前是第幾節課,用了幾次,現在在哪,然而這樣並不可行。這道題本質是讓我們去求在哪節課去申請調換,因此是否申請必須從狀態之中表現出來,因此我們的狀態為當前是第幾節課,用了幾次,這次是否申請,當時我為了方便容易自己理解,設定了三種狀態,0.未申請 1.申請但失敗 2.申請且成功(2,3中不體現本次是否成功的概率,僅在轉移是體現)。於是這樣我們的轉移方程就出來了。

1        f[i][0][0]=f[i-1][0][0]+dis[c[i-1

]][c[i]];

3if(j<=i-2) f[i][j][0]=min(f[i-1][j][0]+dis[c1][cc],(f[i-1][j][1]+dis[c1][cc])*(1-k[i-1])+(f[i-1][j][2]+dis[d1][cc])*k[i-1

]);4

else

if(j<=i-1) f[i][j][0]=(f[i-1][j][1]+dis[c1][cc])*(1-k[i-1])+(f[i-1][j][2]+dis[d1][cc])*k[i-1];5

if(j==i)f[i][j][0]=0x7ffffff

;6 f[i][j][1]=min(f[i-1][j-1][0]+dis[c1][cc],(f[i-1][j-1][1]+dis[c1][cc])*(1-k[i-1])+(f[i-1][j-1][2]+dis[d1][cc])*k[i-1

]);7 f[i][j][2]=min(f[i-1][j-1][0]+dis[c1][dd],(f[i-1][j-1][1]+dis[c1][dd])*(1-k[i-1])+(f[i-1][j-1][2]+dis[d1][dd])*k[i-1

]);8

if(j==1)9

但是這樣我們還有三個點是過不了的,因為我們在這裡忽略了乙個事情,1,2必須從同一位置轉移,也就是說我們這樣可能導致1,2乙個是從上次申請轉移過來,乙個是從上次未申請轉移過來,然後就wa成狗了。

所以我們要引進乙個2.0版。

1        f[i][0][0]=f[i-1][0][0]+dis[c[i-1

]][c[i]];

2if((f[i-1][j-1][0]+dis[c1][cc])*(1.0-k[i])+(f[i-1][j-1][0]+dis[c1][dd])*k[i]-0.000000001>((f[i-1][j-1][1]+dis[c1][dd])*(1.0-k[i-1])+(f[i-1][j-1][2]+dis[d1][dd])*k[i-1])*k[i]+((f[i-1][j-1][1]+dis[c1][cc])*(1.0-k[i-1])+(f[i-1][j-1][2]+dis[d1][cc])*k[i-1])*(1.0-k[i]))37

else

8road[180005

];19

void build(int x,int y,int

z)26

bool rd[450

];27

double dis[450][450

];28 queueq1;

29void spfa(int

t)50}51

}52}53

}54double f[2001][2005][3

];55

intmain()

75for(int i=1;i<=v;i++)

7680 k[0]=1

;81 f[0][0][0]=f[0][0][1]=0.0;82

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

8397

else

98102

if(j==1

)103

108}

109}

110double ans=f[n][0][0

];111

for(int i=1;i<=m;i++)

112115 printf("

%.2lf\n

",ans);

116//

while(1);

117return0;

118 }

view code

NOIP 2016 提高組 換教室

先用弗洛伊德求出兩兩點的最短路,設dp fi j,0 表示當前走到了i這個點,申請了j次,在原點的期望距離,fi j,1 表示當前走到了i這個點,申請了j次,在申請點的期望距離 當然要加上沒有申請成功走到原點的期望距離 轉移 設ds 0 1,0 1 表示從上一輪的原點 申請點到當前的原點 申請點距離...

NOIP2016 換教室 期望DP

嗯,noip歷年真題什麼的,到處都有,抓一道就是三四倍經驗題,我就不寫題目描述了23333 偷個懶一定不會被人發現的 事實上,這是我第一次做概率與期望dp的題目,不是很懂套路,然後就想了很久很久,沒什麼太多的頭緒。首先我覺得應該是用f i j 儲存前i個時間段,申請換j次課,期望收穫到的疲勞值。但是...

Noip 2016 換教室 期望DP

期望反映了乙個隨機變數的平均結果,是所有可能結果的概率乘上結果的和。例如對於乙個隨機變數x,1 3機率變為1,1 3機率變為2,1 3機率變為3,則x的期望值為 13 1 1 3 2 13 3 21 3 1 13 2 1 3 3 2期望具有線性性質,我們可以根據加法原理和乘法原理來對期望進行計算 可...