Aizu 2303 Marathon Match 概率dp

题目链接:点击打开链接

题意:

一场马拉松

给定n个运动员,跑道上有m个休息站,马拉松跑道长L

下面n行每行3个参数

表示每个运动员崩溃概率:P 休息时间:E 跑步速度:V。

每个运动员随时会崩溃,崩溃后会坚持到下一个休息站,进入休息他的休息时间。全程匀速运动,可能多次崩溃。

问:

每个运动员成为唯一一个第一名的概率。

思路:

其实可以转换成每个运动员进入下一个休息站的概率是P

每次单独求一个运动员成为第一名的概率。

暴力枚举这个运动员进入休息站的次数。

然后枚举其他的运动员比他慢的概率,相乘得到这个运动员崩溃j次后依然是第一名的概率,相加即是他成为第一名的概率。

#include<bits/stdc++.h>
template <class T>
inline bool rd(T &ret) {
    char c; int sgn;
    if(c=getchar(),c==EOF) return 0;
    while(c!='-'&&(c<'0'||c>'9')) c=getchar();
    sgn=(c=='-')?-1:1;
    ret=(c=='-')?0:(c-'0');
    while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
    ret*=sgn;
    return 1;
}
template <class T>
inline void pt(T x) {
    if (x <0) {
        putchar('-');
        x = -x;
    }
    if(x>9) pt(x/10);
    putchar(x%10+'0');
}
using namespace std;
typedef long long ll;
const int MAXN = 55;
double C[MAXN+1][MAXN+1];
void Initial()
{
    memset(C, 0, sizeof C);
    for(int i=0; i<=MAXN; ++i)
    {
        C[0][i] = 0.0;
        C[i][0] = 1.0;
    }
    for(int i=1; i<=MAXN; ++i)
    {
        for(int j=1; j<=MAXN; ++j)
        C[i][j] = C[i-1][j] + C[i-1][j-1];
    }
}
const int N = 110;
int n, m;
int l, t[N], v[N];
double p[N];
double Pow(double x, int y){
    double ans = 1.0;
    while(y){
        if(y&1)ans *= x;
        x = x*x;
        y >>= 1;
    }
    return ans;
}
double work(int x){
    double ans = 0.0;
    for(int i = 0; i <= m; i++)
    {
        double pp = C[m][i] * Pow(p[x], i) * Pow(1.0-p[x], m-i);
        for(int j = 1; j <= n; j++)
        {
            if(j == x)continue;
            double siz = 0;
            for(int k = m; k >= 0; k--)
            {
                if(l*v[j] + i*t[x]*v[j]*v[x] < l*v[x] + k*t[j]*v[x]*v[j])
                    siz += C[m][k] * Pow(p[j], k) * Pow(1.0-p[j], m-k);
                else break;
            }
            pp *= siz;
        }
        ans += pp;
    }
    return ans;
}
void input(){
    for(int i = 1; i <= n; i++)
        {
            rd(p[i]);rd(t[i]);rd(v[i]);
            p[i] /= 100.0;
        }
}
int main(){
    Initial();
    while(cin>>n>>m>>l){
        input();
        for(int i = 1; i <= n; i++)
            printf("%.10f\n", work(i));
    }
    return 0;
}
/*
30 0 12
0.5
0
13

*/

Marathon Match

Time Limit : 5 sec, Memory Limit : 65536 KB

Marathon Match

N people
run a marathon. There are M resting
places on the way. For each resting place, the i-th
runner takes a break with probability Pi percent.
When the i-th
runner takes a break, he gets rest for Ti time.

The i-th
runner runs at constant speed Vi,
and the distance of the marathon is L.

You are requested to compute the probability for each runner to win the first place. If a runner arrives at the goal with another person at the same time, they are not considered to win the first place.

Input

A dataset is given in the following format:

N M L

P1 T1 V1

P2 T2 V2

PN TN VN

The first line of a dataset contains three integers N (1≤N≤100), M (0≤M≤50)
and L(1≤L≤100,000). N is
the number of runners. M is
the number of resting places. L is
the distance of the marathon.

Each of the following N lines
contains three integers Pi (0≤Pi≤100), Ti (0≤Ti≤100)
and Vi(0≤Vi≤100)
describing the i-th
runner. Pi is
the probability to take a break. Ti is
the time of resting. Vi is
the speed.

Output

For each runner, you should answer the probability of winning. The i-th
line in the output should be the probability that the i-th
runner wins the marathon. Each number in the output should not contain an error greater than 10?5.

Sample Input 1

2 2 50
30 50 1
30 50 2

Output for the Sample Input 1

0.28770000
0.71230000

Sample Input 2

2 1 100
100 100 10
0 100 1

Output for the Sample Input 2

0.00000000
1.00000000

Sample Input 3

3 1 100
50 1 1
50 1 1
50 1 1

Output for the Sample Input 3

0.12500000
0.12500000
0.12500000

Sample Input 4

2 2 50
30 0 1
30 50 2

Output for the Sample Input 4

0.51000000
0.49000000
时间: 2024-10-28 21:31:49

Aizu 2303 Marathon Match 概率dp的相关文章

Aizu 2303 Marathon Match

因为第i个人休息j次服从二项分布,算一下组合数. 数据范围小. 求出第i个人休息j次的概率和对应的时间之后,全概率公式暴力统计. #include<bits/stdc++.h> using namespace std; const int maxn = 101,maxm = 51; int P[maxn],T[maxn],V[maxn]; long long C[maxm][maxm]; double rst[maxn][maxm]; double tim[maxn][maxm]; //con

POJ 3071-Football(概率dp)

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3145   Accepted: 1591 Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In each round of the tournament, all teams still in the

POJ3071-Football(概率DP+滚动数组)

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2769   Accepted: 1413 Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In each round of the tournament, all teams still in the

POJ 3071 Football (动态规划-概率DP)

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2768   Accepted: 1412 Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In each round of the tournament, all teams still in the

[ACM] POJ 3071 Football (概率DP)

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2875   Accepted: 1462 Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In each round of the tournament, all teams still in the

poj3071之概率DP

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2667   Accepted: 1361 Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, -, 2n. In each round of the tournament, all teams still in the

Codeforces 28C [概率DP]

/* 大连热身D题 题意: 有n个人,m个浴室每个浴室有ai个喷头,每个人等概率得选择一个浴室. 每个浴室的人都在喷头前边排队,而且每个浴室内保证大家都尽可能均匀得在喷头后边排队. 求所有浴室中最长队伍的期望. 思路: 概率dp dp[i][j][k]代表前i个浴室有j个人最长队伍是k的概率. 枚举第i个浴室的人数.然后转移的时候其实是一个二项分布. */ #include<bits/stdc++.h> using namespace std; int jilu[55]; double dp[

hdu 3076 ssworld VS DDD (概率dp)

///题意: /// A,B掷骰子,对于每一次点数大者胜,平为和,A先胜了m次A赢,B先胜了n次B赢. ///p1表示a赢,p2表示b赢,p=1-p1-p2表示平局 ///a赢得概率 比一次p1 两次p0*p1 三次 p0^2*p1,即A赢的概率为p1+p*p1+p^2*p1+...p^n*p1,n->无穷 ///即a_win=p1/(1-p);b_win=p2/(1-p); ///dp[i][j]表示a赢了j次,b赢了i次的概率 ///dp[i][j]=dp[i-1][j]*b_win+dp[

hdu 3853 概率DP 简单

http://acm.hdu.edu.cn/showproblem.php?pid=3853 题意:有R*C个格子,一个家伙要从(0,0)走到(R-1,C-1) 每次只有三次方向,分别是不动,向下,向右,告诉你这三个方向的概率,以及每走一步需要耗费两个能量,问你走到终点所需要耗费能量的数学期望: 回头再推次,思想跟以前的做过的类似 注意点:分母为0的处理 #include <cstdio> #include <cstring> #include <algorithm>