日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【DP】【期望】$P1850$换教室

發布時間:2023/12/2 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【DP】【期望】$P1850$换教室 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【DP】【期望】\(P1850\)換教室

鏈接

題目描述

\(2n\) 節課程安排在$ n$ 個時間段上。在第 \(i\)\(1 \leq i \leq n\))個時間段上,兩節內容相同的課程同時在不同的地點進行,其中,牛牛預先被安排在教室 \(c_i\)上課,而另一節課程在教室 \(d_i\)進行。

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

牛牛發現申請更換第\(i\)節課程的教室時,申請被通過的概率是一個已知的實數 \(k_i\),并且對于不同課程的申請,被通過的概率是互相獨立的。

所有的申請只能一次性提交,并且每個人只能選擇至多 \(m\)節課程進行申請。

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

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

輸入格式

第一行四個整數 \(n,m,v,e\)

第二行 \(n\) 個正整數,第 \(i\)\(1 \leq i \leq n\))個正整數表示 c\(c_i\),即第\(i\)個時間段牛牛被安排上課的教室;保證 \(1 \le c_i \le v\)

第三行 \(n\) 個正整數,第 \(i\)\(1 \leq i \leq n\))個正整數表示 \(d_i\),即第 $i $個時間段另一間上同樣課程的教室;保證 \(1 \le d_i \le v\)

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

接下來 \(e\) 行,每行三個正整數 \(a_j, b_j, w_j\),表示有一條雙向道路連接教室 \(a_j, b_j\),通過這條道路需要耗費的體力值是 \(w_j\);保證 \(1 \le a_j, b_j \le v\)\(1 \le w_j \le 100\)

保證 \(1 \leq n \leq 2000\)\(0 \leq m \leq 2000\)\(1 \leq v \leq 300\)\(0 \leq e \leq 90000\)

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

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

輸出格式

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

測試數據保證四舍五入后的答案和準確答案的差的絕對值不大于 \(4 \times 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

提示

  • 道路中可能會有多條雙向道路連接相同的兩間教室。 也有可能有道路兩端連接的是同一間教室。
  • 請注意區分\(n,m,v,e\)的意義, \(n\)不是教室的數量, \(m\)不是道路的數量。
  • \(Solution\)

    考慮DP。狀態怎么設?顯然第幾節課需要在狀態里。還要保證最多換\(m\)次,因此次數也要在狀態里。那么,怎么從上一節課轉移呢?顯然如果我們不知道上一節課在哪個教室上的,就無法轉移。因此,還要在加一維,記錄當前是否申請換教室。

    因此,狀態就是\(f[i][j][k], 1 \leq i \leq n, 0 \leq j \leq m, 0 \leq k \leq 1\),表示前\(i\)節課,換了\(j\)次教室,第\(i\)次換或不換的期望。

    至于轉移則比較簡單了

    f[i][j][0] = min(f[i - 1][j][0] + w[c[i]][c[i - 1]], f[i - 1][j][1] + w[c[i]][d[i - 1]] * k[i - 1] + w[c[i]][c[i - 1]] * (1 - k[i - 1])); f[i][j][1] = min(f[i - 1][j - 1][0] + w[c[i]][c[i - 1]] * (1 - k[i]) + w[d[i]][c[i - 1]] * k[i],f[i - 1][j - 1][1] + w[d[i]][d[i - 1]] * k[i - 1] * k[i] + w[c[i]][c[i - 1]] * (1 - k[i - 1]) * (1 - k[i])+ w[c[i - 1]][d[i]] * (1 - k[i - 1]) * k[i]+ w[d[i - 1]][c[i]] * k[i - 1] * (1 - k[i]));

    如圖為當前不選擇換教室

    如圖為當前選擇換教室

    這道題還有幾點需要主意的,在預處理部分。具體看代碼

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; long long read(){long long x = 0; int f = 0; char c = getchar();while(c < '0' || c > '9') f |= c == '-', c = getchar();while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();return f? -x:x; }int n, m, V, E, c[2002], d[2002], w[305][305]; double f[2002][2002][2], k[2002], ans; int main(){memset(w, 63, sizeof w);//距離初始化n = read(); m = read(); V = read(); E = read();for(int i = 1; i <= n; ++i) c[i] = read();for(int i = 1; i <= n; ++i) d[i] = read();for(int i = 1; i <= n; ++i) scanf("%lf", &k[i]);for(int i = 1; i <= E; ++i){int x = read(), y = read(), z = read();w[x][y] = w[y][x] = min(w[x][y], z);//有可能重邊}for(int l = 1; l <= V; ++l)for(int i = 1; i <= V; ++i)for(int j = 1; j <= V; ++j)w[i][j] = min(w[i][j], w[i][l] + w[l][j]);//floyed最短路for(int i = 1; i <= V; ++i) w[i][i] = w[i][0] = w[0][i] = 0;//初始化for(int i = 1; i <= n; ++i) f[i][0][0] = f[i - 1][0][0] + w[c[i]][c[i - 1]], f[i][0][1] = 1e9;//初始化,處理一個也不申請的情況for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j){f[i][j][0] = min(f[i - 1][j][0] + w[c[i]][c[i - 1]], f[i - 1][j][1] + w[c[i]][d[i - 1]] * k[i - 1] + w[c[i]][c[i - 1]] * (1 - k[i - 1]));f[i][j][1] = min(f[i - 1][j - 1][0] + w[c[i]][c[i - 1]] * (1 - k[i]) + w[d[i]][c[i - 1]] * k[i],f[i - 1][j - 1][1] + w[d[i]][d[i - 1]] * k[i - 1] * k[i] + w[c[i]][c[i - 1]] * (1 - k[i - 1]) * (1 - k[i])+ w[c[i - 1]][d[i]] * (1 - k[i - 1]) * k[i]+ w[d[i - 1]][c[i]] * k[i - 1] * (1 - k[i]));}double ans = f[n][0][0];for(int i = 1; i <= m; ++i) ans = min(ans, min(f[n][i][1], f[n][i][0]));//更新答案printf("%.2lf", ans);return 0; }

    轉載于:https://www.cnblogs.com/kylinbalck/p/11258482.html

    總結

    以上是生活随笔為你收集整理的【DP】【期望】$P1850$换教室的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。