zoukankan      html  css  js  c++  java
  • ZOJ 3380 Patchouli's Spell Cards(概率DP)

    Patchouli's Spell Cards

    Time Limit: 7 Seconds      Memory Limit: 65536 KB

    Patchouli Knowledge, the unmoving great library, is a magician who has settled down in the Scarlet Devil Mansion (紅魔館). Her specialty is elemental magic employing the seven elements fire, water, wood, metal, earth, sun, and moon. So she can cast different spell cards like Water Sign "Princess Undine", Moon Sign "Silent Selene" and Sun Sign "Royal Flare". In addition, she can combine the elements as well. So she can also cast high-level spell cards like Metal & Water Sign "Mercury Poison" and Fire, Water, Wood, Metal & Earth Sign "Philosopher's Stones" .

    Assume that there are m different elements in total, each element has n different phase. Patchouli can use many different elements in a single spell card, as long as these elements have the same phases. The level of a spell card is determined by the number of different elements used in it. When Patchouli is going to have a fight, she will choose m different elements, each of which will have a random phase with the same probability. What's the probability that she can cast a spell card of which the level is no less than l, namely a spell card using at least l different elements.

    Input

    There are multiple cases. Each case contains three integers 1 ≤ m, n, l ≤ 100. Process to the end of file.

    Output

    For each case, output the probability as irreducible fraction. If it is impossible, output "mukyu~" instead.

    Sample Input

    7 6 5
    7 7 7
    7 8 9
    

    Sample Output

    187/15552
    1/117649
    mukyu~
    

    References

    上海アリス幻樂団

    acm_x_touhou


    Author: WU, Zejun
    Source: ACM × Touhou
    Contest: ZOJ Monthly, August 2010

    /*
     * ZOJ 3380
     * 题目意思:有m个位置,每个位置填入一个数,数的范围是1~n,问至少有L个位置的数一样的概率
     * 输出要是最简分数的形式,所以用大数JAVA
     * 至少有L个位置一样,就是L,L+1,L+2····m个位置一样。
     * 我们从反面来考虑,总数是n^m,我们求没有L个位置一样的数的概率
     * 设 dp[i][j]表示用前i个数,填充j个位置的方案数(要符合没有L个位置是一样的数)
     * dp[i][j]=dp[i-1][j]+Sigm( dp[i-1][j-k]*C[m-(j-k)][k]  ) k<=j&&k<L
     * 其实就是看第i个数,可以不填,填一个位置,两个位置······这样累加过来。
     * 那么最后的答案就是 (n^m-dp[1~n][m])/(n^m)
     */

    主要是大数比较麻烦。所以就用JAVA写了,当是练习下JAVA吧!

    /*
     * ZOJ 3380
     * 题目意思:有m个位置,每个位置填入一个数,数的范围是1~n,问至少有L个位置的数一样的概率
     * 输出要是最简分数的形式,所以用大数JAVA
     * 至少有L个位置一样,就是L,L+1,L+2····m个位置一样。
     * 我们从反面来考虑,总数是n^m,我们求没有L个位置一样的数的概率
     * 设 dp[i][j]表示用前i个数,填充j个位置的方案数(要符合没有L个位置是一样的数)
     * dp[i][j]=dp[i-1][j]+Sigm( dp[i-1][j-k]*C[m-(j-k)][k]  ) k<=j&&k<L
     * 其实就是看第i个数,可以不填,填一个位置,两个位置······这样累加过来。
     * 那么最后的答案就是 (n^m-dp[1~n][m])/(n^m)
     */
    import java.util.*;
    import java.io.*;
    import java.math.*;
    public class Main
    {
        static BigInteger[][] dp=new  BigInteger[110][110];
        static BigInteger[][] C=new BigInteger[110][110];//组合数
        public static void main(String arg[])
        {
            Scanner cin=new Scanner(new BufferedInputStream(System.in));
            for(int i=0;i<105;i++)
            {
                C[i][0]=C[i][i]=BigInteger.ONE;
                for(int j=1;j<i;j++)
                    C[i][j]=C[i-1][j-1].add(C[i-1][j]);
            }
            int N,M,L;
            while(cin.hasNext())
            {
                M=cin.nextInt();
                N=cin.nextInt();
                L=cin.nextInt();
                BigInteger tol=BigInteger.valueOf(N).pow(M);
                if(L>M)
                {
                    System.out.println("mukyu~");
                    continue;
                }
                if(L>M/2)//这个时候可以直接用组合数求出来
                {
                    BigInteger ans=BigInteger.ZERO;
                    for(int i=L;i<=M;i++)
                        ans=ans.add(C[M][i].multiply(BigInteger.valueOf(N-1).pow(M-i)));
                    ans=ans.multiply(BigInteger.valueOf(N));
                    BigInteger gcd=ans.gcd(tol);
                    System.out.println(ans.divide(gcd)+"/"+tol.divide(gcd));
                    continue;
                }
                for(int i=0;i<=N;i++)
                     for(int j=0;j<=M;j++)
                     {
                         dp[i][j]=BigInteger.ZERO;
                     }
                dp[0][0]=BigInteger.ONE;
                for(int i=1;i<=N;i++)
                    for(int j=1;j<=M;j++)
                    {
                        for(int k=0;k<L&&k<=j;k++)
                            dp[i][j]=dp[i][j].add(dp[i-1][j-k].multiply(C[M-(j-k)][k]));
                    }
               BigInteger ans=BigInteger.ZERO;
               for(int i=1;i<=N;i++)
                   ans=ans.add(dp[i][M]);    
               ans=tol.subtract(ans);
               BigInteger gcd=ans.gcd(tol);
               System.out.println(ans.divide(gcd)+"/"+tol.divide(gcd));
            }
        }
    }
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    netstat命令查看服务器运行情况
    分布式架构进化之路
    显示器 Linux 性能 18 (一个命令行工具传递)
    _00024 尼娜抹微笑伊拉克_云计算ClouderaManager以及CHD5.1.0群集部署安装文档V1.0
    CMDeviceMotion使用
    Ubuntu 安装和配置minicom
    树阵
    HTML5在input背景提示文本(placeholder)的CSS美化
    PowerDesigner反projectM连接ySql没有mySql odbc驱动器
    Flume 1.5日志收集和存款mongodb安装结构
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2712980.html
Copyright © 2011-2022 走看看