zoukankan      html  css  js  c++  java
  • 猜球球

    题面:

    有n个盒子,有个小球小球出现在每个盒子的概率为p[i],你现在可以问类似(小球是否在盒子{1,4,……,n}中?)(1-n的一个子集)的问题,问策略最优情况下,猜出小球所在盒子的猜测次数的数学期望。

    思路:

    因为任意一次询问和回答,都可以确定其中一半的球球集合包含目标球,另一半则不包含目标球。然后再对包含目标球的球球集合进一步划分,直到包含目标球的集合里只包含一个球,就可以百分百确定了。这样就得到了一个决策树(二叉形状),二叉决策树根节点到每个叶子的路到都是期中一种情况的解决方案,显然深度就是询问次数。 则有:

    期望=∑(询问次数每种情况出现的概率)

    =∑(叶子对应的深度它出现在盒子里的概率)。

    而我们知道:这个公式 ∑(深度*元素出现的概率 ) 与某种编码方案的编码长度期望公式 相同。询问次数的期望最小也就是编码长度的期望最小。而解决这个问题的经典方法就是——哈夫曼树。

    一句话总结:构造一棵哈夫曼树,然后有

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef pair<double,int>pa;
     4 const int N=20000;
     5  
     6 vector<int> G[N];
     7 double a[N],ans;
     8 int n,cnt;
     9 priority_queue<pa,vector<pa>,greater<pa> >q;
    10  
    11 void dfs(int x, int d) {
    12     if (G[x].size() == 0) ans += a[x] * d;
    13     for (auto it : G[x]) {
    14         dfs(it, d + 1);
    15     }
    16 }
    17 int main() {
    18     scanf("%d",&n);
    19     for (int i=1;i<=n;i++) {
    20         scanf("%lf", &a[i]);
    21         if (a[i] == 0) {
    22             n--;
    23             i--;
    24             continue;
    25         }
    26         q.push(pa(a[i], i));
    27     }
    28     cnt=n;
    29     while (q.size() >= 2) {
    30         pa t1 = q.top();
    31         q.pop();
    32         pa t2 = q.top();
    33         q.pop();
    34         pa t3(t1.first + t2.first, ++cnt);
    35         q.push(t3);
    36         G[cnt].push_back(t1.second);
    37         G[cnt].push_back(t2.second);
    38     }
    39     dfs(q.top().second, 0);
    40     printf("%.7lf
    ", ans);
    41 }
    View Code
  • 相关阅读:
    在Windows Phone应用中使用Google Map替代Bing Map
    《从入门到精通:Windows Phone 7应用开发》
    判断最小割的唯一性
    ASP.NET页面生命周期
    SQL排序
    window.open
    VS2008中英文转换
    asp.net下载文件的常用方法
    TSQL Convert转换时间类型
    TreeView
  • 原文地址:https://www.cnblogs.com/Accpted/p/11185521.html
Copyright © 2011-2022 走看看