首页 > 试题广场 >

无聊的牛牛和羊羊

[编程题]无聊的牛牛和羊羊
  • 热度指数:2235 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
牛牛和羊羊非常无聊.他们有n + m个共同朋友,他们中有n个是无聊的,m个是不无聊的。每个小时牛牛和羊羊随机选择两个不同的朋友A和B.(如果存在多种可能的pair(A, B),任意一个被选到的概率相同。),然后牛牛会和朋友A进行交谈,羊羊会和朋友B进行交谈。在交谈之后,如果被选择的朋友之前不是无聊会变得无聊。现在你需要计算让所有朋友变得无聊所需要的时间的期望值。

输入描述:
输入包括两个整数n 和 m(1 ≤ n, m ≤ 50)


输出描述:
输出一个实数,表示需要时间的期望值,四舍五入保留一位小数。
示例1

输入

2 1

输出

1.5
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n, m, s;
    scanf("%d%d", &n, &m);
    double f[m+1];
    s = n + m;
    double p = 1.0*s*(s-1)/2;
    for(int i=1;i<=m;i++){
        int x=i, y=s-i;
        double a = 1.0*y*(y-1)/2 / p;
        double b = 1.0*y*x / p;
        double c = 1.0*x*(x-1)/2 / p;
        f[i] += b*(f[i-1]+1);
        if(i>1)
            f[i] += c*(f[i-2]+1);
        f[i] += a;
        f[i] /= (1-a);
    }
    printf("%.1lf\n", f[m]);
    return 0;
}

发表于 2020-10-13 01:04:35 回复(0)
发表于 2019-05-23 11:49:16 回复(1)
#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <cmath>

using namespace std;

double roundk(double num, int k) {
    return round(num * pow(10, k)) / pow(10, k);
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int s = n + m;
    double f0 = 0, f1 = s / 2.0;
    for(int k = 2; k <= m; k++) {
        double cur = s * (s - 1) / (1.0 * k * (2 * s - k - 1)) + 2 * (s - k) * 1.0 / (2 * s - k - 1) * f1 + (k - 1) * 1.0 / (2 * s - k - 1) * f0;
        f0 = f1;
        f1 = cur;
    }
    printf("%.1f\n", roundk(f1, 1));
    return 0;
}

本题考察递推公式,设总共有s个0,1(s >= 2),每次从其中随机选出2个,将这两个数中的1变成0,试求平均多少次操作后,s个数全部变成0.

当s个数中有k个1时,设平均需要f(k)次操作使得s个数全部变成0.一次操作后有3种可能性,即k --> k, k --> k - 1, k --> k - 2.分别表示取出了00, 01或10,11.这三种情况的概率分别为C(s - k, 2)/C(s, 2), (s - k) * k / C(s, 2), C(k, 2)/C(s, 2). 由此可以得到f(k)的递推公式.

f(k) = 1 + C(s - k, 2) / C(s, 2) f(k) + (s - k) k / C(s, 2) f(k - 1) + C(k, 2) / C(s, 2) f(k - 2)

化简此递推公式,即得到k到k-1,k-2的递推公式。当k=1时,是特殊情况,由分析可以得到f(1) = f(0) + s / 2, f(0) = 0.综上得解.

编辑于 2018-02-24 13:42:34 回复(10)
def fun(n, m):
    if m <= 0:
        return 0
    elif m == 1:
        return (n + m) / 2
    else:
        s = ((m + n) * (m + n -1)) / 2
        m_2 = m * (m - 1) / 2
        m_1 = m
        n_1 = n
        n_2 = n * (n - 1) / 2
        fz = 1 + ((m_2 * fun(n+2, m - 2))/ s) + ((m * n * fun(n+1, m - 1)) / s)
        fm = (1 - (n_2 / s))
        sum = fz/fm
        return sum

if __name__ == "__main__":
    n, m = map(int, input().split())
    print(round(fun(n, m),1))

未能在规定时间内运行结束,可以怎么改呢

发表于 2019-03-21 11:07:37 回复(2)
const readline=require('readline');
const rl=readline.createInterface({
input:process.stdin,
output:process.stdout
})
var mark=new Array();
var result=new Array();
rl.on("line",function(line){
var arr=line.split(' ');
var n=parseInt(arr[0]);
var m=parseInt(arr[1]);
for(var i=0;i<100;i++)
{
mark[i]=new Array();
result[i]=new Array();
for(var j=0;j<100;j++)
{
mark[i][j]=false;
result[i][j]=0;
}
}
var time=DFS(n,m);
console.log(time.toFixed(1));
process.exit(0);
});
function DFS(n,m){
if(m<=0){
return 0;
}
if(mark[n][m]===true)
{
return result[n][m];
}
var p1=n*(n-1)/((n+m)*(n+m-1));
var p2=2*n*m/((n+m)*(n+m-1));
var p3=m*(m-1)/((n+m)*(n+m-1));
result[n][m]=(1+p2*DFS(n+1,m-1)+p3*DFS(n+2,m-2))/(1-p1);
mark[n][m]=true;
return result[n][m];
}

编辑于 2019-03-17 16:41:08 回复(0)
max_value = 101
n_input, m_input = map(int, input().strip().split())
mark_lst = [[0 for _ in range(max_value)] for _ in range(max_value)]
value_lst = [[0 for _ in range(max_value)] for _ in range(max_value)]


def func_1(n, m):
    if m <= 0:
        return 0
    if mark_lst[n][m]:
        return value_lst[n][m]
    else:
        s = (n + m) * (n + m - 1) / 2
        p_1 = n * (n - 1) / 2
        p_2 = n * m
        p_3 = m * (m - 1) / 2
        a = p_2 / (s - p_1)
        b = p_3 / (s - p_1)
        c = s / (s - p_1)
        value_lst[n][m] = a * func_1(n + 1, m - 1) + b * func_1(n + 2, m - 2) + c
        mark_lst[n][m] = 1
        return value_lst[n][m]


print(round(func_1(n_input, m_input), 1))
发表于 2019-02-20 19:47:21 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author wylu
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] strs = br.readLine().split(" ");
        int n = Integer.parseInt(strs[0]), m = Integer.parseInt(strs[1]);

        int total = n + m;
        double[] f = new double[m + 1];
        f[0] = 0;
        f[1] = total / 2.0;

        double s = total * (total - 1) / 2.0;
        for (int i = 2; i <= m; i++) {
            double tmp = total - i;
            double p1 = tmp * (tmp - 1) / 2.0 / s;
            double p2 = tmp * i / s;
            double p3 = i * (i - 1) / 2.0 / s;
            f[i] = (1 + p2 * f[i - 1] + p3 * f[i - 2]) / (1 - p1);
        }
        System.out.println(String.format("%.1f", f[m]));
    }
}

发表于 2019-01-25 20:36:05 回复(0)
#include<stdio.h>
double f[100];
int main()
{
    int yes,no,all;
    scanf("%d%d",&yes,&no);
    all=yes+no;
    double pos=(double)all*(all-1)/2;
    for(int i=1;i<=no;i++)
    {
        int n=i,y=all-i;
        double c1=((double)y*(y-1)/2)/pos;
        double c2=(double)y*n/pos;
        double c3=((double)n*(n-1)/2)/pos;
        f[i]+=c2*(f[i-1]+1);
        if(i>=2) f[i]+=c3*(f[i-2]+1);
        f[i]+=c1;
        f[i]=f[i]/(1-c1);
    }
    printf("%.1lf",f[no]);
    return 0;
}
//列出公式后计算就好了

发表于 2017-12-14 12:49:14 回复(0)
#include<stack>
#include<algorithm>
#include <iostream>
#include <iomanip>

using namespace std;
#define maxn 55
float dp[maxn];
int n,m;
float p1(int x,float deno){
    return (n+x)*(m-x) / deno;
}
float p2(int x,float deno){
    return (m-x)*(m-x-1)/2.0f/deno;
}
float p3(int x,float deno){
    return (n+x)*(n+x-1)/2.0f/deno;
}
int main(){

    while(cin >> n >> m){
        float deno = (n+m)*(n+m-1) / 2.0f;
        for(int i = 0;i < maxn;i ++){
            dp[i] = 0.0f;
        }
        for(int i = m-1;i >=0;i --){
            dp[i] += (dp[i+1]+1)*p1(i,deno) + p3(i,deno);
            if(i+2 <=m){
                dp[i] += p2(i,deno) * (dp[i+2] + 1);
            }
            dp[i] /= (1-p3(i,deno));
        }
        cout << setiosflags(ios::fixed) << setprecision(1) << dp[0] << endl;
    }
    return 0;
}
发表于 2017-12-07 12:55:51 回复(0)