poj 2057 树形DP,数学期望
題目鏈接:http://poj.org/problem?id=2057
題意:有一只蝸牛爬上樹睡著之后從樹上掉下來,發(fā)現(xiàn)后面的"房子"卻丟在了樹上面, 現(xiàn)在這只蝸牛要求尋找它的房子,它又得從樹根開始爬起,現(xiàn)在要求一條路徑使得其找到房子
所要爬行的期望距離最小. 爬行距離如下計算, 題目規(guī)定每一個分支和枝末都看做是一個節(jié)點, 這些節(jié)點之間的距離都是1, 在分支上可能會有熱心的毛毛蟲, 這些毛毛蟲會如實的告訴蝸牛他之前是否經(jīng)過這條路徑, 也正是因為毛毛蟲, 因此詢問毛毛蟲的順序使得這題的期望是不同的. 輸入數(shù)據(jù)時給定的一個鄰接關(guān)系,通過上一個節(jié)點來構(gòu)圖 ;同時字符 'Y'表示該點有毛毛蟲, 字符'N'表示該點
分析:
die[i]表示以 i 為根結(jié)點找不到房子時要爬行的最少距離。
當(dāng) i 沒有毛毛蟲的時候 ?j 是 i 的子節(jié)點。
當(dāng) i 有毛毛蟲的時候 ;
?
win[i]表示以 i 為根結(jié)點時,選好所有分支后,枚舉完所有房子落在所有葉子結(jié)點的時候,要爬的最短距離。
就是說:當(dāng)我走到 j 而找到時,前面的都失敗了。而 j 成功了。j 子樹 又有很多葉子結(jié)點。其中只有一個是成功的(并不知道是哪個)。
如圖:
?
然后就是對于 i 結(jié)點來說,怎么訪問才使得重復(fù)結(jié)點最少。
那就是?
1 #include <cstdio> 2 #include <iostream> 3 #include <vector> 4 #include <algorithm> 5 #include <cstring> 6 7 using namespace std; 8 9 const int maxn = 1010; 10 int pos[maxn]; 11 int snode[maxn]; 12 int die[maxn]; 13 int win[maxn]; 14 int n; 15 16 vector<int>vec[maxn]; 17 18 void init() 19 { 20 memset(pos,0,sizeof(pos)); 21 memset(snode,0,sizeof(snode)); 22 memset(die,0,sizeof(die)); 23 memset(win,0,sizeof(win)); 24 25 char ps; 26 int pre; 27 for(int i=1;i<=n;i++) { 28 vec[i].clear(); 29 } 30 31 for(int i=1;i<=n;i++) { 32 scanf("%d %c%*c",&pre,&ps); 33 if(pre==-1) continue; 34 vec[pre].push_back(i); 35 if(ps=='Y') pos[i] = 1; 36 } 37 } 38 39 int cmp(int a,int b) { 40 return (die[a]+2)*snode[b]<(die[b]+2)*snode[a]; 41 } 42 43 void dfs(int x) { 44 int len = vec[x].size(); 45 for(int i=0;i<len;i++) 46 dfs(vec[x][i]); 47 if(len ==0) 48 { 49 snode[x] = 1; 50 die[x] = 0; 51 win[x] = 0; 52 return; 53 } 54 for(int i=0;i<len;i++) { 55 snode[x] +=snode[vec[x][i]]; 56 if(pos[x]==0) die[x] +=die[vec[x][i]] + 2; 57 } 58 59 int tmp[10]; 60 for(int i=0;i<len;i++) { 61 tmp[i] = vec[x][i]; 62 } 63 64 int sum = 0; 65 sort(tmp,tmp+len,cmp); 66 for(int i=0;i<len;i++) { 67 win[x] +=(sum+1)*snode[tmp[i]] + win[tmp[i]]; 68 sum +=die[tmp[i]]+2; 69 } 70 71 } 72 73 int main() 74 { 75 while(scanf("%d%*c",&n),n) { 76 init(); 77 double ans; 78 dfs(1); 79 ans = 1.0*win[1]/snode[1]; 80 printf("%.4lf\n",ans); 81 } 82 return 0; 83 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/TreeDream/p/6537632.html
總結(jié)
以上是生活随笔為你收集整理的poj 2057 树形DP,数学期望的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: zookeeper leader选举机制
- 下一篇: 营养师和健康管理师有什么不同吗