HDU 5753 Permutation Bo 排列组合& 期望 多校3

来源:互联网 发布:数据库系统工程师教材 编辑:程序博客网 时间:2024/06/16 16:23

HDU 5753 排列组合

题意:对于全排列h,h数组是一个1~n的数,只要对应的位置大于两端,相应的位置的c数组中的书就加进去。 
这里写图片描述


思路:对小于三的数进行特判,把整个序列分为两种情况,中间的和两端的。对中间的任一种情况进行计算就可以。对中间的情况必须放大于2的数才能有满足条件的值,当中间放的值为i时比i小的值有i-1个从i-1个数中选出两个不同的数进行全排列有(i-1)*(i-2)中不同的情况剩下的n-3个值进行全排列(n-3)!与前面的(i-1)*(i-2)相乘。最后再除n!的全排列,得到中间的值得权值。之后就可以得到答案。

对于两边的权值放的值必须大于1会有满足条件的情况,当放的值为i时,比它小的值有i-1种情况从2到n遍历一遍把全部的情况记录下来。除n的阶乘。这里要注意n的阶乘会爆long long 所以注意自己把公式写出来把分母分母进行约分,比赛时就是没有进行优化直接进行n的阶乘所以一直找错,浪费了好长时间。


附AC代码:

#include <iostream>#include <stdio.h>#include <cmath>#include <algorithm>#include <cstring>using namespace std;typedef long long ll;typedef long long LL;ll c[1010];int main(){    int n;    while(~scanf("%d",&n))    {        for(int i=1;i<=n;i++)        {            scanf("%I64d",&c[i]);        }        if(n>=3)        {            double res=0;///代表结果            double zh=0,bi=0;///zh代表中间的权值,bi代表边界的权值            for(int i=3;i<=n;i++)            {                zh+=(i-1)*(i-2);            }            zh=zh*1.0/(n*(n-1)*(n-2));///中间的权值            for(int i=2;i<n;i++)            {                res+=zh*c[i];///将中间的权值乘中间的数加到结果中            }            for(int i=2;i<=n;i++)            {                bi+=(i-1);            }            bi=bi*1.0/(n*(n-1));///边界的权值            res+=bi*c[1]+bi*c[n];///边界的权值乘边界的值            printf("%.6lf\n",res);        }        else if(n==2)        {            double tmp;            tmp=(c[1]*1.0+c[2]*1.0)/2;            printf("%.6lf\n",tmp);        }        else///对1进行特判        {            printf("%d.000000\n",c[1]);        }    }    return 0;}


0 0
原创粉丝点击