codeforces 601C(概率dp)

题目链接

C. Kleofáš and the n-thlon
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Kleofáš is participating in an n-thlon - a tournament consisting of n different competitions in n different disciplines (numbered 1 through n). There are m participants in the n-thlon and each of them participates in all competitions.

In each of these n competitions, the participants are given ranks from 1 to m in such a way that no two participants are given the same rank - in other words, the ranks in each competition form a permutation of numbers from 1 to m. The score of a participant in a competition is equal to his/her rank in it.

The overall score of each participant is computed as the sum of that participant's scores in all competitions.

The overall rank of each participant is equal to 1 + k, where k is the number of participants with strictly smaller overall score.

The n-thlon is over now, but the results haven't been published yet. Kleofáš still remembers his ranks in each particular competition; however, he doesn't remember anything about how well the other participants did. Therefore, Kleofáš would like to know his expected overall rank.

All competitors are equally good at each discipline, so all rankings (permutations of ranks of everyone except Kleofáš) in each competition are equiprobable.

Input

The first line of the input contains two space-separated integers n (1 ≤ n ≤ 100) and m (1 ≤ m ≤ 1000) — the number of competitions and the number of participants respectively.

Then, n lines follow. The i-th of them contains one integer xi (1 ≤ xi ≤ m) — the rank of Kleofáš in the i-th competition.

Output

Output a single real number – the expected overall rank of Kleofáš. Your answer will be considered correct if its relative or absolute error doesn't exceed 10 - 9.

Namely: let's assume that your answer is a, and the answer of the jury is b. The checker program will consider your answer correct, if .

Sample test(s)
Input
4 10
2
1
2
1
Output
1.0000000000000000
Input
5 5
1
2
3
4
5
Output
2.7500000000000000
Input
3 6
2
4
2
Output
1.6799999999999999
Note

In the first sample, Kleofáš has overall score 6. Nobody else can have overall score less than 6 (but it's possible for one other person to have overall score 6 as well), so his overall rank must be 1.

题意:m个人参加n项全能比赛。每项比赛每个人都会有一个排名,排名也为该选手在该项比赛上的得分,一个人最后总得分为所有比赛得分之和,他的排名为得分严格小于他的人的人数+1。现在一个人,只记得他每场比赛的排名。假设所有人的实力均等,每场比赛出现的结果的概率相同。求这个人最后排名的期望值。

题解:最后要求解那个人的排名,就是求解得分小于他的得分的期望人数。

我们用dp[i][j]表示,前i项比赛,得分为j的期望人数,转移就是:

dp[i][j]=sum(dp[i-1][k]*1/(m-1)),j-m<=k<=j-1,k!=j-x[i] (x[i]为第i场比赛该人的排名)

转移可以优化到O(1).

复杂度O(n*n*m)

代码如下:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<list>
typedef __int64 LL;
typedef unsigned __int64 LLU;
const int nn=110;
const int inf=0x3fffffff;
const LL inf64=(LL)inf*inf;
using namespace std;
int n,m;
int a[nn];
double dp[nn][nn*1000];
double sum[nn][nn*1000];
int main()
{
    int i,j;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int tem=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            tem+=a[i];
        }
        if(m==1)
        {
            printf("%d\n",1);
            continue;
        }
        memset(dp,0,sizeof(dp));
        dp[0][0]=m-1;
        sum[0][0]=0;
        for(i=1;i<=n*m+1;i++)
        {
            sum[0][i]=m-1;
        }
        for(i=1;i<=n;i++)
        {
            sum[i][0]=0;
            sum[i][1]=0;
            for(j=1;j<=n*m;j++)
            {
                int r=j,l=max(0,j-m);
                dp[i][j]+=(sum[i-1][r]-sum[i-1][l])*1.0/(m-1);
                if(j-a[i]>=0)
                    dp[i][j]-=dp[i-1][j-a[i]]*1.0/(m-1);
                sum[i][j+1]=sum[i][j]+dp[i][j];
            }
        }
        printf("%.12lf\n",sum[n][tem]+1);
    }
    return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值