zoukankan      html  css  js  c++  java
  • 🔺 Garbage Remembering Exam UVA

    题目大意:给你N个单词,有两种方法随机排列,一种随机排成一行,另一种随机排成一圈,当两个单词之间的距离在两种排列中都严格小于K时,则这两个单词构成无效单词,问无效单词的期望。
    解题思路:首先对于一排单词的每个单词,取出距离它为K的单词,然后把取出的单词放到环形序列的这个单词的两边
    如果我们能分别算出1-n的有效概率,那么就等于算出了无效概率

    其中 x为当前单词的左右距离为k的单词的个数, 分子是把一排单词中一个单词的有效距离的单词取出来全排列到环形的无效距离内,然后剩余的单词全排列;

    考虑到排列与组合数据过大,用  exp()函数,其中log(N!)=log(N)+log(N-1)+...+log(1);

    需要注意  用long double能过。。。

    代码如下:

    没大弄明白为什么n-1-x < 2*k 的时候不考虑

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define N 100005
    long double temp[N];
    int n,k;
    double solve()
    {
        if(n==1) return 0;//只有一个单词,无效为0
        else if(2*k+1>=n) return n;//如果圈中的一个单词从左边或右边距离都小于K,则该单词无效,所有单词等效
        double ret=0;
        for(int i=1;i<=n;i++)
        {
            int x=min(k,i-1)+min(k,n-i);//一个单词左右k范围内的单词个数
            if(n-1-x-2*k>=0)
            {
                ret+=exp(temp[n-1-x]+temp[n-1-2*k]-temp[n-1]-temp[n-1-x-2*k]);
            }
    //        else
    //            ret += exp(temp[2*k] - temp[2*k-n+1+x] + temp[x] - temp[n-1]);
        }
        return n-ret;
    }
    int main()
    {
        temp[0]=0;
        for(int i=1;i<N;i++)
            temp[i]=temp[i-1]+log((long double)i);
        int cas=1;
        while(scanf("%d%d",&n,&k))
        {
            if(n==0&&k==0) break;
            printf("Case %d: %.4lf
    ",cas++,solve());
        }
        return 0;
    }
    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    让Visual Studio 2008 和 2010支持Web Services Enhancements (WSE) 3.0
    不清楚BA的角色是什么
    int的一点事,读《深入C#内存管理来分析值类型&引用类型,装箱&拆箱,堆栈几个概念组合之间的区别》
    Angular2.0视频教程来了!
    [11]缺少动态连接库.socannot open shared object file: No such file or directory
    计算机网络常考知识点总结
    计算机网络——数据链路层
    计算机网络——物理层
    Java内存模型_基础
    JAVA_Lock
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9354057.html
Copyright © 2011-2022 走看看