湫湫系列故事——植树节 HDU4503

题目大意

题目链接

有n个小朋友,编号1到n。每个小朋友有Bi个朋友(1<=i<=n)。现要选出的3个小朋友都互为朋友,或都不是朋友。求任意选出3人满足条件的概率。

题解

简单分析一下可以发现,题目没有告诉具体的关系。那要求概率只能用组合数学。该题有两种思考方向,一种直接求满足条件的方案数,一种是反着求不满足条件的方案数。

1. 正向求解

易知,任意选出3个人他们之间的关系有且只有以下4种情况:1)三人互为朋友;2)三人都不是朋友;3)三个人中只有两个人是朋友;4)三个人中只有两个人不是朋友;

我们设总方案数为z = C^{3}_{n}, 情况1)的方案数为:A,情况2)为B,情况3)为C,情况4)为D,则z = A+B+C+D。

如果我们从每个人的朋友中选两人 C^{2}_{B_{i}},那么加上这个人,这三人的关系就可能为情况1)或情况4);

对每一个人都做如上操作,并求和得到方案数X = \sum_{i=1}^{n}C^{2}_{B_{i}},且X=3*A+D。3*A是因为情况1)再计算时被充分计算了3次。

同理,如果我们从每个的非朋友中选两人,并对每一个人做同样的操作,最后在求和。便可得到Y=\sum_{i=1}^{n}C^{2}_{n-B_{i}-1},且Y=3*B+C。

之后,有z = A+B+C+D,X=3*A+D和Y=3*B+C便可解出A+B = \tfrac{X+Y-Z}{2},那么概率P = \frac{A+B}{A+B+C+D} = \frac{X+Y-Z}{2*Z}

代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int arr[1002];

int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        int n;
        scanf("%d", &n);
        for(int i = 0; i<n; i++){
            scanf("%d", arr+i);
        }
        int z = n*(n-1)*(n-2)/6;
        int x = 0, y = 0;
        for(int i = 0; i<n; i++){
            y += arr[i]*(arr[i]-1)/2;
            x += (n-arr[i]-1)*(n-arr[i]-2)/2;
        }
        printf("%.3f\n", 1.0*(x+y-z)/2/z);
    }
}

2. 反向求解

 对于每一个人,我们都从他的朋友中取一人C^{1}_{B_{i}},再从他非朋友中取一人C_{n-B_{i}-1}^{1}。通过这种方式选出的三人的关系为情况3)或情况4),且都重复计算了2次。则对每一个人做同样的操作,并求和得到方案数:S=\sum_{i=1}^{n}B_{i}*(n-B_{i}-1) = 2*(C+D)。

所以概率P=\frac{Z-S/2}{Z}

代码如下:

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int arr[1002];

int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        int n;
        scanf("%d", &n);
        for(int i = 0; i<n; i++){
            scanf("%d", arr+i);
        }
        int tol = n*(n-1)*(n-2)/6;
        int fail = 0;
        for(int i = 0; i<n; i++){
            fail+=(arr[i]*(n-arr[i]-1));
        }
        printf("%.3f\n", 1.0*(tol-1.0*fail/2)/tol);
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值