ZOJ 3380 Patchouli's Spell Cards (概率dp)

题意:有m种元素,每种元素可以配n种phase之一;相同phase的元素可以组成一张spell card,card的等级为元素的种数, 问m种元素随机生成的card有多少概率使他的等级至少为l

 

dp[i][j]为用前i种phase生成i种元素有多少种情况

dp[i][j] = dp[i][j-k] * C[m-j+k][k] ( k >= 0 && k <= j && k < l )

意思是用第i种phase去生成k个元素

则答案为  ( n^m - dp[1~n][m] ) / ( n^m );

 

import java.math.*;
import java.io.*;
import java.util.*;



public class Main  {
	static BigInteger[][] dp = new BigInteger[111][111];
	static BigInteger[][] C = new BigInteger[111][111];
	
	static public void main ( String [] args ) {
		Scanner cin = new Scanner( System.in );
		for( int i = 0;i < 110; 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();
			if ( l > m ) {
				System.out.println( "mukyu~");
				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 ) {
					dp[i][j] = dp[i][j].add( dp[i-1][j] );
					for( int k = 1; k <= j && k < l; ++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] );
			//System.out.println( ans );
			BigInteger tot = BigInteger.valueOf( n ).pow( m );
			ans = tot.subtract( ans );
			BigInteger tmp = ans.gcd( tot );
			System.out.println( ans.divide( tmp ) +"/" + tot.divide( tmp ) );
		}
	}
	
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值