zoukankan      html  css  js  c++  java
  • Bzoj4481 [Jsoi2015]非诚勿扰

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 147  Solved: 75

    Description

    【故事背景】
    JYY赶上了互联网创业的大潮,为非常勿扰开发了最新的手机App实现单身大龄青年之间的“速配”。然而随着用户数量的增长,JYY发现现有速配的算法似乎很难满足大家的要求,因此JYY决定请你来调查一下其中的原因。
    【问题描述】
    应用的后台一共有N个女性和M个男性,他们每个人都希望能够找到自己的合适伴侣。为了方便,每个男性都被编上了1到N之间的一个号码,并且任意两个人的号码不一样。每个女性也被如此编号。

    JYY应用的最大特点是赋予女性较高的选择权,让每个女性指定自己的“如意郎君列表”。每个女性的如意郎君列表都是所有男性的一个子集,并且可能为空。如果列表非空,她们会在其中选择一个男性作为自己最终接受的对象。
    JYY用如下算法来为每个女性速配最终接受的男性:将“如意郎君列表”中的男性按照编号从小到大的顺序呈现给她。对于每次呈现,她将独立地以P的概率接受这个男性(换言之,会以1−P的概率拒绝这个男性)。如果她选择了拒绝,App就会呈现列表中下一个男性,以此类推。如果列表中所有的男性都已经呈现,那么中介所会重新按照列表的顺序来呈现这些男性,直到她接受了某个男性为止。
    显然,在这种规则下,每个女性只能选择接受一个男性,而一个男性可能被多个女性所接受。当然,也可能有部分男性不被任何一个女性接受。这样,每个女性就有了自己接受的男性(“如意郎君列表”为空的除外)。现在考虑任意两个不同的、如意郎君列表非空的女性a和b,如果a的编号比b的编号小,而a选择的男性的编号比b选择的编号大,那么女性a和女性b就叫做一对不稳定因素。
    由于每个女性选择的男性是有一定的随机性的,所以不稳定因素的数目也是有一定随机性的。JYY希望你能够求得不稳定因素的期望个数(即平均数目),从而进一步研究为什么速配算法不能满足大家的需求。

    Input

    输入第一行包含2个自然数N,M,表示有N个女性和N个男性,以及所有女
    性的“如意郎君列表”长度之和是M。
    接下来一行一个实数P,为女性接受男性的概率。
    接下来M行,每行包含两个整数a,b,表示男性b在女性a的“如意郎君列表”
    中。
    输入保证每个女性的“如意郎君列表”中的男性出现切仅出现一次。
    1≤N,M≤500,000,0.4≤P<0.6

    Output

    输出1行,包含一个实数,四舍五入后保留到小数点后2位,表示不稳定因素的期望数目。

    Sample Input

    5 5
    0.5
    5 1
    3 2
    2 2
    2 1
    3 1

    Sample Output

    0.89

    HINT

    Source

    数学问题 期望 脑洞题

    期望还能这么玩儿,真的神奇。

    女方如果选中某个人,可能是第一轮选中的,也可能是第一轮没选人,在第二轮选中的,也可能在第三轮,第四轮……

    看上去是个无限项的等比数列求和。

    利用等比数列公式计算女方选某个人的概率:

      $ frac{a_1*(1-p^n)}{1-p}$

    在n无穷大的时候$ p^n $趋近于0,可以直接忽视掉。

    这样就可以算出这个位置被选的概率。

    这样,之后开始选择的女方如果选了某个更靠前位置,就多了这么些概率贡献一个逆序对。

    将边按双关键字排序,用树状数组维护一个类似逆序对的东西即可。

    数据卡精度,需要long double

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<cstring>
     7 using namespace std;
     8 const int mxn=500010;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 struct edge{
    16     int x,y;
    17     bool operator < (const edge &b)const{
    18         return ((x==b.x && y<b.y) || x<b.x);
    19     }
    20 }a[mxn],c[mxn];
    21 //
    22 int n,m;
    23 int len[mxn];
    24 long double P,pr[mxn];
    25 long double t[mxn];
    26 void add(int x,double v){while(x<=n){t[x]+=v;x+=x&-x;}}
    27 long double ask(int x){double res=0.0;while(x){res+=t[x];x-=x&-x;}return res;};
    28 inline long double GetP(int x,int y){return P*pr[y-1]/(1-pr[len[x]]);}
    29 int main(){
    30 //    freopen("in.txt","r",stdin);
    31     n=read();m=read();scanf("%Lf",&P);
    32     pr[0]=1.0;
    33     for(int i=1;i<=m;i++){pr[i]=pr[i-1]*(1-P);}
    34     for(int i=1;i<=m;i++){
    35         a[i].x=read();a[i].y=read();len[a[i].x]++;
    36     }
    37     sort(a+1,a+m+1);
    38     long double ans=0.0;
    39     int hd=1;
    40     for(int i=1;i<=n;i++){//枚举左边
    41         if(a[hd].x!=i)continue;
    42         int cnt=0;
    43         while(a[hd].x==i){
    44             ++cnt;
    45             add(a[hd].y,GetP(i,cnt));
    46             ans+=GetP(i,cnt)*(ask(n)-ask(a[hd].y));
    47             hd++;
    48         }
    49     }
    50     printf("%.2f
    ",(double)ans);
    51     return 0;
    52 }
  • 相关阅读:
    网站安全编程 黑客入侵 脚本黑客 高级语法入侵 C/C++ C# PHP JSP 编程
    【算法导论】贪心算法,递归算法,动态规划算法总结
    cocoa2dx tiled map添加tile翻转功能
    8月30日上海ORACLE大会演讲PPT下载
    【算法导论】双调欧几里得旅行商问题
    Codeforces Round #501 (Div. 3) B. Obtaining the String (思维,字符串)
    Codeforces Round #498 (Div. 3) D. Two Strings Swaps (思维)
    Educational Codeforces Round 89 (Rated for Div. 2) B. Shuffle (数学,区间)
    洛谷 P1379 八数码难题 (BFS)
    Educational Codeforces Round 89 (Rated for Div. 2) A. Shovels and Swords (贪心)
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6946847.html
Copyright © 2011-2022 走看看