当前位置: 代码迷 >> 综合 >> ZOJ 3380 Patchouli's Spell Cards [基础概率DP+大数]
  详细解决方案

ZOJ 3380 Patchouli's Spell Cards [基础概率DP+大数]

热度:16   发布时间:2023-12-06 19:46:02.0
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 ≤ mnl ≤ 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~

题意:

抽象的来说,就是给你M个不同的球,N种颜色,现在给球染色,问至少有L个球同一种颜色的概率。

解法:

总方案数很好算,为N^M,剩下的就是求至少L个球同色的方案数,其可以转换为 (总方案数-每种颜色至多L-1个球的方案数)。

然后就是很明显的DP了,DP[I][J]表示已放完I种颜色,剩下J个球的方案数,那么转移方程为

DP[I+1][J-K]+=DP[I][J]*C(J,K) 其中C()为组合数,K为当前颜色装的球数。

tip:

GCD(总方案数-每种颜色至多L-1个球的方案数,总方案数)==GCD每种颜色至多L-1个球的方案数,总方案数

import java.math.BigInteger;
import java.util.Scanner;public class Main {static BigInteger[][] dp = new BigInteger[105][105];static BigInteger[][] c = new BigInteger[105][105];static void init(){c[0][0] = BigInteger.valueOf(1);for(int i = 1; i <= 100; i++){c[i][0] = c[i][i]= BigInteger.valueOf(1);for(int j = 1; j < i; j++)c[i][j] = c[i-1][j-1].add(c[i-1][j]);}}static int min(int x, int y){return x < y ? x : y;}static void solve(int m, int n, int l){BigInteger fm = BigInteger.valueOf(n).pow(m);for(int i = 0; i <= n+1; i++)for(int j = 0; j <= m; j++)dp[i][j] = BigInteger.ZERO;dp[0][m] = BigInteger.ONE;for(int i = 1; i <= n; i++)for(int j = 0; j <= m; j++)for(int k = 0; k <= min(j,min(m,l-1)); k++)dp[i][j-k] = dp[i][j-k].add(dp[i-1][j].multiply(c[j][k]));BigInteger fz = dp[n][0];BigInteger gcd = fm.gcd(fz);fz = fm.subtract(fz).divide(gcd);fm = fm.divide(gcd);System.out.println(fz + "/" + fm);}public static void main(String[] args) {init();Scanner cin = new Scanner(System.in);int m, n, l;while(cin.hasNext()){m = cin.nextInt();n = cin.nextInt();l = cin.nextInt();if(l > m)System.out.println("mukyu~");elsesolve(m, n, l);}cin.close();}
}