- 题目描述:
-
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
- 输入:
-
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
- 输出:
-
对输入的每组数据M和N,用一行输出相应的K。
- 样例输入:
-
1 7 3
- 样例输出:
-
8
解法1用dp(m, n) = dp(m - n, n) + f(m, n - 1) +...+ f(m, 1) 其中dp(m, n)表示将m个苹果放到n个盘子里的解的个数,f(m, n -1)表示将m个苹果放到n-1个盘子里,每个盘子都有青苹果的解的个数 ,而dp(m, n)和f(m, n-1)的关系为dp(m - 1 + n, n -1) = f(m, n - 1)
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Scanner;
class Main
{
public static final boolean DEBUG = false;
public static int dp(int m, int n)
{
if ((m == 1 || m == 0) && n >= 1) return 1;
if (m < 0) return 0;
int s1 = 0, s2 = 0;
s1 = dp(m - n, n);
for (int i = 1; i < n; i++) {
s2 += dp(m + i - n, n - i);
}
return s1 + s2;
}
public static void main(String[] args) throws IOException
{
Scanner cin;
int m, n, t;
if (DEBUG) {
cin = new Scanner(new FileReader("d:\\OJ\\uva_in.txt"));
} else {
cin = new Scanner(new InputStreamReader(System.in));
}
t = cin.nextInt();
while (t-- > 0) {
m = cin.nextInt();
n = cin.nextInt();
System.out.println(dp(m, n));
}
}
}
解法2:其递归式为dp(m,n) = dp(m - n, n) + dp(m, n - 1),其中dp(m - n, n)表示每个盘子都有苹果的解的个数,dp(m, n - 1)表示有一个盘子里没有苹果的解的个数
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Scanner;
class Main
{
public static final boolean DEBUG = false;
public static int dp(int m, int n)
{
if (n == 1) return 1;
else if (m == 1 || m == 0) return 1;
else if (m < 0) return 0;
else {
return dp(m - n, n) + dp(m, n - 1);
}
}
public static void main(String[] args) throws IOException
{
Scanner cin;
int m, n, t;
if (DEBUG) {
cin = new Scanner(new FileReader("d:\\OJ\\uva_in.txt"));
} else {
cin = new Scanner(new InputStreamReader(System.in));
}
t = cin.nextInt();
while (t-- > 0) {
m = cin.nextInt();
n = cin.nextInt();
System.out.println(dp(m, n));
}
}
}
解法3:dp(m, n, i)表示当前盘子放i个苹果 , dp(m, n, 1) = dp(m, n - 1, 1) + dp(m, n - 1, 2) +... + dp(m, n - 1, m)
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Scanner;
class Main
{
public static final boolean DEBUG = false;
public static int dp(int m, int n, int a)
{
if (m == 0) return 1;
else if (n == 0 && m > 0) return 0;
else if (m > 0 && m < a) return 0;
else {
int sum = 0;
for (int i = a; i <= m; i++) {
sum += dp(m - i, n - 1, i);
}
return sum;
}
}
public static void main(String[] args) throws IOException
{
Scanner cin;
int m, n, t;
if (DEBUG) {
cin = new Scanner(new FileReader("d:\\OJ\\uva_in.txt"));
} else {
cin = new Scanner(new InputStreamReader(System.in));
}
t = cin.nextInt();
while (t-- > 0) {
m = cin.nextInt();
n = cin.nextInt();
System.out.println(dp(m, n, 1));
}
}
}