Problem Description
有n种物品,并且知道每种物品的数量。要求从中选出m件物品的排列数。例如有两种物品A,B,并且数量都是1,从中选2件物品,则排列有"AB","BA"两种。
Input
每组输入数据有两行,第一行是二个数n,m(1<=m,n<=10),表示物品数,第二行有n个数,分别表示这n件物品的数量。
Output
对应每组数据输出排列数。(任何运算不会超出2^31的范围)
Sample Input
2 2 1 1
Sample Output
2
题意:给出n个元素及每个元素的个数,从中选出m个,求其排列数
思路:指数母函数方法
代码如下
import java.io.FileInputStream;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;
public class Main implements Runnable
{
private static final boolean DEBUG = false;
private Scanner cin;
private PrintWriter cout;
private int n, m;
private static final int N = 11;
private static final int[] fact = new int[N];
private static final int[] c = new int[N];
private void init()
{
try {
if (DEBUG) {
cin = new Scanner(new InputStreamReader(new FileInputStream("f:\\OJ\\uva_in.txt")));
} else {
cin = new Scanner(new InputStreamReader(System.in));
}
cout = new PrintWriter(new OutputStreamWriter(System.out));
fact[0] = 1;
for (int i = 1; i < N; i++) {
fact[i] = i * fact[i - 1];
}
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean input()
{
if (!cin.hasNextInt()) return false;
n = cin.nextInt();
m = cin.nextInt();
for (int i = 0; i < n; i++) {
c[i] = cin.nextInt();
}
return true;
}
private void solve()
{
double[] a = new double[N];
double[] b = new double[N];
for (int i = 0; i <= c[0]; i++) {
a[i] = 1.0 / fact[i];
}
for (int i = 1; i < n; i++) {
for (int j = 0; j <= m; j++) {
for (int k = 0; k <= c[i] && j + k <= m; k++) {
b[j + k] += a[j] / fact[k];
}
}
for (int j = 0; j <= m; j++) {
a[j] = b[j];
b[j] = 0;
}
}
cout.printf("%.0f", a[m] * fact[m]);
cout.println();
cout.flush();
}
@Override
public void run()
{
init();
while (input())
{
solve();
}
}
public static void main(String[] args)
{
// TODO code application logic here
new Thread(new Main()).start();
}
}