题目描述:
有M个小孩到公园玩,门票是1元。其中N个小孩带的钱为1元,K个小孩带的钱为2元。售票员没有零钱,问这些小孩共有多少种排队方法,使得售票员总能找得开零钱。注意:两个拿一元零钱的小孩,他们的位置互换,也算是一种新的排法。(M<=10)
输入:
输入一行,M,N,K(其中M=N+K,M<=10).
输出:
输出一行,总的排队方案。
样例输入:
4 2 2
样例输出:
8
解题思路:
从题目中可以了解到为了使售票员能够找零钱,所以第一个小孩必须是带的钱为1元,而最后一个小孩则带的钱是两元。这一步完成后则采取DFS算法,跟在第一个小孩后面的可以是携带一元的,也可以是携带两元的,如果是第二种可能,则需继续仿照第一步。
例子:
小孩人数:4
携带一元的小孩人数:2
携带两元的小孩人数:2
假设一元小孩为:a 二元小孩分别为:b
画出DFS:
总共有10种情况,我们从题目了解到,最后位只能是b,所以只有①②③⑤⑥⑧暂时符合条件,但是⑧它是abbaab并不符合条件,所以只有五种情况,我们因此可以构建出相关函数:
public static int DFS(int N, int K)
{
if(K>N)
return 0;
if(K==0)
return 1;
return DFS(N-1,K)+DFS(N,K-1);
}
而题目中又提到每个小孩是单独的个体(注意:两个拿一元零钱的小孩,他们的位置互换,也算是一种新的排法。(M<=10))
所以我们还需要给每个小孩排序a=>a1,a2,a3 b=>b1,b2,b3
构建出相关函数:
public static int paixu(int temp)
{
int s = 1;
for(int i=1; i<=temp; i++)
{
s*=i;
}
return s;
}
全部代码和结果截图:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int M = scanner.nextInt();
int N = scanner.nextInt();
int K = scanner.nextInt();
System.out.println(DFS(N,K)*paixu(N)*paixu(K));
}
}
public static int DFS(int N, int K)
{
if(K>N)
return 0;
if(K==0)
return 1;
return DFS(N-1,K)+DFS(N,K-1);
}
public static int paixu(int temp)
{
int s = 1;
for(int i=1; i<=temp; i++)
{
s*=i;
}
return s;
}
}