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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

BZOJ 4720 [Noip2016]换教室

發布時間:2024/9/5 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 4720 [Noip2016]换教室 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

4720: [Noip2016]換教室

Description

對于剛上大學的牛牛來說,他面臨的第一個問題是如何根據實際情況申請合適的課程。在可以選擇的課程中,有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)節課結束后,牛牛就會從這節課的教室出發,選擇一條耗費體力最少的路徑前往下一節課的教室。現在牛牛想知道,申請哪幾門課程可以使他因在教室間移動耗費的體力值的總和的期望值最小,請你幫他求出這個最小值。

Input

第一行四個整數n,m,v,e。n表示這個學期內的時間段的數量;m表示牛牛最多可以申請更換多少節課程的教室; v表示牛牛學校里教室的數量;e表示牛牛的學校里道路的數量。 第二行n個正整數,第i(1≤i≤n)個正整數表示c,,即第i個時間段牛牛被安排上課的教室;保證1≤ci≤v。 第三行n個正整數,第i(1≤i≤n)個正整數表示di,即第i個時間段另一間上同樣課程的教室;保證1≤di≤v。 第四行n個實數,第i(1≤i≤n)個實數表示ki,即牛牛申請在第i個時間段更換教室獲得通過的概率。保證0≤ki≤1。 接下來e行,每行三個正整數aj,bj,wj,表示有一條雙向道路連接教室aj,bj,通過這條道路需要耗費的體力值是Wj; 保證1≤aj,bj≤v,1≤wj≤100。 保證1≤n≤2000,0≤m≤2000,1≤v≤300,0≤e≤90000。 保證通過學校里的道路,從任何一間教室出發,都能到達其他所有的教室。 保證輸入的實數最多包含3位小數。

Output

輸出一行,包含一個實數,四舎五入精確到小數點后恰好2位,表示答案。你的 輸出必須和標準輸出完全一樣才算正確。 測試數據保證四舎五入后的答案和準確答案的差的絕對值不大于4*10^-3。(如果你不知道什么是浮點誤差,這段話可以理解為:對于大多數的算法,你可以正常地使用浮點數類型而不用對它進行特殊的處理)

Sample Input

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

Sample Output

2.80
  這道題也可以算得上是經典了。當時考NOIP碰到這道題,當時還壯志滿懷,很長的一道題(至少當時看來是這樣的)很快就被我讀完了,發現可以分成三份:課程、教室,申請、概率,道路、耗費體力最少。   當時,我的很多同學見此題太長,就根本沒有看。此題雖然沾期望,但其實很簡單。 ----------因為后面扯的東西比較多,就在這里講一下思路。----------   我們這樣開數組:f[2][2][M],第一維枚舉課程但可以“滾動”(cur),第二位判斷在第i門課程是否提交申請,第三維給現在已申請的課程計一下數。空間是O(M)的,時間是O(NM)的,最后輸出f[cur][j][p](j=0,1; p=0,1,...,m)   這樣,我們可以考慮轉移。一個課程如果沒有申請,那就是100%的“純爺們兒”教室c。但如果申請了呢?可以YY一下薛定諤的貓,有概率的事件可以當做對立統一的個體。也就是說一個課程如果申請了,就可以看做k[i]個d教室和1-k[i]個c教室,實際轉移時思考一下即可。   關于方程可以看看我的代碼(本文末尾)。 ----------好的,思路講完了。我可以開始扯了。----------   當時我高興極了,發現可以把課程當做i,把申請數當做j,把此時是否申請當0/1。當時才學了DP,只會背包(還是最簡單的)和floyd,什么LIS、數位、狀壓(NOIPD2T3ANGRYBIRD)、樹形都不知道,更不用說什么概率和期望了……然而就是考了。YJQ表示,不要再逼我吃鍵盤了。   關于吃鍵盤一事,都是因為——YJQ說NOIP絕對不考期望DPNOIP這么水的考試怎么可能考這種東西寫個暴力就A題的比賽要是考了這種東西我就直播吃鍵盤……YJQ其實是一個很謹慎的人,不像lemonoil每天立下flag要直播吃掉∞個鍵盤。 兜售巧克力味鍵盤了喂!專門為立flag死掉的人設計的喂~~~”   所以就是這樣的。然而我當時就是想到了如何去做,雖然現在看完題就可以切過去。因為當時我既會背包,也會floyd。不過,天有不測風云,我當時的代碼實現能力實在是太弱了……
  弱到什么地步?也就是說,我發現當時k數組定義的是int類型……也許,質問當時的我,我還會義憤填膺地說,int不就是數么整數是數小數難道不是數么?!   呃呃呃呃呃。   然而,當我現在做到這道題時,當我已經“掌握”了概率與期望的時候,還是WA。   恩。請來客忽略我的強制調劑(eyeprotect)。一邊調,一會兒AC,一會兒又WA的體驗真的是第一回碰到。更令人驚奇的是,中間居然還有CE,讓人頗為尷尬。要是NOIP也這樣,那恐怕就只有再見OI了。   最后突然發現,卡了這么久竟是這兩個原因。   1.memset(dis,65,sizeof(dis))很明顯是錯的,因為在floyd內部,dis+dis會跳負。應將65改成63或127/2。   2.這個地方才真正調了我很久,這個地方是讓人非常尷尬的。DP中常常有x=std::min(x,y);的語句出現,但我在修改時只把第一個x改對了……所以說需要有#define smin(x,y) x=std::min(x,y)啊(YYF、mcfx等大佬強力推薦)!   最后掛一波代碼吧。 1 /************************************************************** 2 Problem: 4720 3 User: Doggu 4 Language: C++ 5 Result: Accepted 6 Time:1960 ms 7 Memory:1292 kb 8 ****************************************************************/ 9 10 #define PN "classroom" 11 #include <cstdio> 12 #include <cstring> 13 #include <algorithm> 14 #define smin(x,y) x=std::min(x,y) 15 const int N = 2000+50; 16 const int M = 2000+50; 17 const int V = 300+10; 18 int n, m, v, e, c[N], d[N], dis[V][V], cur=0; 19 double k[N], f[2][2][M]; 20 21 int main() { 22 scanf("%d%d%d%d",&n,&m,&v,&e); 23 for( int i = 1; i <= n; i++ ) scanf("%d",&c[i]); 24 for( int i = 1; i <= n; i++ ) scanf("%d",&d[i]); 25 for( int i = 1; i <= n; i++ ) scanf("%lf",&k[i]); 26 memset(dis,63,sizeof(dis)); 27 for( int i = 1,a,b,w; i <= e; i++ ) { 28 scanf("%d%d%d",&a,&b,&w); 29 if(dis[a][b]>w) dis[a][b]=dis[b][a]=w; 30 } 31 for( int i = 1; i <= v; i++ ) dis[i][i]=0; 32 for( int p = 1; p <= v; p++ ) 33 for( int i = 1; i <= v; i++ ) 34 for( int j = 1; j <= v; j++ ) 35 if (dis[i][j]>dis[i][p]+dis[p][j]) 36 dis[i][j]=dis[i][p]+dis[p][j], 37 dis[j][i]=dis[i][j]; 38 memset(f[cur],127,sizeof(f[cur]));f[cur][0][0]=f[cur][1][1]=0; 39 for( int i = 2; i <= n; i++ ) { 40 cur^=1;memset(f[cur],127,sizeof(f[cur])); 41 for( int p = 0; p <= m; p++ ) { 42 smin(f[cur][0][p],f[cur^1][1][p]+k[i-1]*dis[c[i]][d[i-1]]+(1-k[i-1])*dis[c[i]][c[i-1]]); 43 smin(f[cur][0][p],f[cur^1][0][p]+dis[c[i]][c[i-1]]); 44 smin(f[cur][1][p+1],f[cur^1][1][p]+k[i]*k[i-1]*dis[d[i]][d[i-1]]+(1-k[i])*k[i-1]*dis[c[i]][d[i-1]]+k[i]*(1-k[i-1])*dis[d[i]][c[i-1]]+(1-k[i])*(1-k[i-1])*dis[c[i]][c[i-1]]); 45 smin(f[cur][1][p+1],f[cur^1][0][p]+k[i]*dis[d[i]][c[i-1]]+(1-k[i])*dis[c[i]][c[i-1]]); 46 } 47 } 48 double ans=2000000000; 49 for( int j = 0; j <= 1; j++ ) 50 for( int p = 0; p <= m; p++ ) 51 ans=std::min(ans,f[cur][j][p]); 52 printf("%.2lf\n",ans); 53 return 0; 54 } 55 NOIP第一道期望DP

轉載于:https://www.cnblogs.com/Doggu/p/bzoj4720.html

總結

以上是生活随笔為你收集整理的BZOJ 4720 [Noip2016]换教室的全部內容,希望文章能夠幫你解決所遇到的問題。

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