1. 程式人生 > >【NOIP2016提高組day1】?換教室

【NOIP2016提高組day1】?換教室

獲得 表示 牛牛 所在 進行 發現 更換 學校 而且

題目

對於剛上大學的牛牛來說,他面臨的第一個問題是如何根據實際情況申請合適的
課程。
在可以選擇的課程中,有 2n 節課程安排在 n 個時間段上。 在第 i ( 1 ≤ i ≤ n )個 時間段上,兩節內容相同的課程同時在不同的地點進行,其中,牛牛預先被安排在教室 ci 上課,而另一節課程在教室 di 進行。
在不提交任何申請的情況下,學生們需要按時間段的順序依次完成所有的 n 節安排好的課程。如果學生想更換第i節課程的教室,則需要提出申請。若申請通過,學生就可以在第 i 個時間段去教室 di 上課,否則仍然在教室 ci 上課。由於更換教室的需求太多,申請不一定能獲得通過。 通過計算,牛牛發現申請更 換第 i 節課程的教室時,申請被通過的概率是一個己知的實數 ki ,並且對於不同課程 的申請,被通過的概率是互相獨立的。

學校規定,所有的申請只能在學期開始前一次性提交,並且每個人只能選擇至多m節課程進行申請。 這意味著牛牛必須一次性決定是否申請更換每節課的教室,而不能根據某些課程的申請結果來決定其他課程是否申請;牛牛可以申請自己最希望更換教室的 m 門課程,也可以不用完這 m 個申請的機會,甚至可以一門課程都不申請。 因為不同的課程可能會被安排在不同的教室進行,所以牛牛需要利用課間時間從 一間教室趕到另一間教室。 牛牛所在的大學有 v 個教室,有 e 條道路。 每條道路連接兩間教室,並且是可 以雙向通行的。
由於道路的長度和擁堵程度不同,通過不同的道路耗費的體力可能會有所不同。 當第 i ( 1 ≤ i ≤ n ? 1 )節課結束後,牛牛就會從這節課的教室出發,選擇一條耗費體力最少的路徑前往下一節課的教室。現在牛牛想知道,申請哪幾門課程可以使他因在教室間移動耗費的體力值的總和的期望值最小,請你幫他求出這個最小值。
現在牛牛想知道,申請哪幾門課程可以使他因在教室間移動耗費的體力值的總和的期望值最小,請你幫他求出這個最小值。

分析

這道題其實只要熟悉期望的求法,而且腦子沒有炸掉都可以想出來(反正我腦子是炸掉了)
首先用floyd將教室兩兩間到達的距離求出來。
求期望,搞個dp,
\(f_{i,j,0|1}\)表示做到第i節課,用了j次申請,這節課有沒有申請(k=0表示沒有,反之),的最小期望值。
轉移很容易,就是有點麻煩甚至惡心:

f[i][j][0]=min(f[i][j][0],f[i-1][j][0]+dis[a[i-1][0]][a[i][0]]);
            if(j>=1)
            {
                f[i][j][0]=min(f[i][j][0],
                    (f[i-1][j][1]+dis[a[i-1][1]][a[i][0]])*s[i-1]+
                    (f[i-1][j][1]+dis[a[i-1][0]][a[i][0]])*(1-s[i-1]));
                f[i][j][1]=min(f[i][j][1],
                    (f[i-1][j-1][0]+dis[a[i-1][0]][a[i][1]])*s[i]+
                    (f[i-1][j-1][0]+dis[a[i-1][0]][a[i][0]])*(1-s[i]));
                if(j>=2)
                {
                    f[i][j][1]=min(f[i][j][1],
                        (f[i-1][j-1][1]+dis[a[i-1][1]][a[i][1]])*s[i]*s[i-1]+
                        (f[i-1][j-1][1]+dis[a[i-1][1]][a[i][0]])*(1-s[i])*s[i-1]+
                        (f[i-1][j-1][1]+dis[a[i-1][0]][a[i][1]])*s[i]*(1-s[i-1])+
                        (f[i-1][j-1][1]+dis[a[i-1][0]][a[i][0]])*(1-s[i])*(1-s[i-1]));
                }
            }

【NOIP2016提高組day1】?換教室