zoukankan      html  css  js  c++  java
  • 【codeforces 602E】Kleofáš and the n-thlon

    time limit per test1 second
    memory limit per test256 megabytes
    inputstandard input
    outputstandard 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 .

    Examples
    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.

    【题目链接】:http://codeforces.com/contest/602/problem/E

    【题解】

    除了这个人x之外,其余m-1个人;
    每个人到达某个分数的概率都是一样的;
    所以只考虑一个人的情况就好了;
    设f[i][j]表示一个人在前i轮考试里面,得到分数为i的概率是多少;
    设x这个人的得分为myscore;
    则最后的答案就为1+(m-1)*∑f[n][i] (i∈[1,myscore-1])
    一个人得到分数i的几率为p[i]
    则m-1个人得到分数i的期望人数就为(m-1)*p[i]
    上面那个∑号左边再加上1,就是x所在的排名了;
    状态转移方程是
    f[i][j] = (f[i-1][j-1]+f[i-1][j-2]+f[i-1][j-3]…f[i-1][j-m] - f[i-1][j-x[i]])/(m-1);
    这里的左边那m个加起来的东西是表示从这些状态可以转移到当前状态,但是有一个排名为x[i]的已经被x号占据了,所以要减去;
    然后这m-1个转移的几率都是1/(m-1);
    这m-1个转移可以写成前缀和的形式;
    用滚动数组写一下;

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%I64d",&x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int MAXN = 1e2+10;
    const int MAXM = 1e3+10;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int n,m,pre,now,scores=0;
    double f[2][MAXN*MAXM];
    
    double get_pre(int x)
    {
        if (x < 0)
            return 0;
        else
            return f[pre][x];
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        rei(n);rei(m);
        if (m==1)
        {
            puts("1");
            return 0;
        }
        pre = 0,now = 1;
        rep1(i,0,n*m)
            f[0][i] = 1;
        double fenmu = 1.0/(m-1);
        rep1(i,1,n)
        {
            int x;
            rei(x);
            scores+=x;
            int ma = i*m;
            rep1(j,0,n*m)
                f[now][j] = 0;
            rep1(j,i,ma)
            {
                double temp = get_pre(j-1)-get_pre(j-m-1)-(get_pre(j-x)-get_pre(j-x-1));
                f[now][j] = fenmu*temp;
            }
            rep1(j,i,ma+m)
                f[now][j] += f[now][j-1];
            now = now^1,pre = pre^1;
        }
        double ans = f[pre][scores-1]*(m-1)+1;
        printf("%.12f
    ",ans);
        return 0;
    }
  • 相关阅读:
    [转]document对象execCommand的命令参数介绍
    Windows蓝屏说明
    PHP手册下载
    编写简单的代码生成工具
    EXCEL中标记两列中都存在的数据,过滤B列中存在A列中不存在的数据[原创]
    SC Create 添加服务不成功(总弹帮助信息)的原因[转]
    Excel中删除两列中重复的数据[原创]
    禁止更改桌面背景及活动桌面的批处理_最终版[原创]
    EXCEL中自动检测当前单元格或上一单元格在列A中是否存在相同数据[原创]
    EXCEL中避免同一列及相邻列中出现重复数据[原创]
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626757.html
Copyright © 2011-2022 走看看