题目链接:http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid=2§ionid=2&problemid=10
参照文章:http://www.cnblogs.com/kuangbin/archive/2012/03/21/2410516.html
题目大意:火车的出站顺序,类似于n个元素先进栈后出栈顺序,比如有三个元素abc,用1表示进栈,0表示出栈
a进 b进 c进 c出 b出 a出 1 1 1 0 0 0
a进 a出 b进 c进 c出 b出 1 0 1 1 0 0
a进 b进 b出 c进 c出 a出 1 1 0 1 0 0
a进 a出 b进 b出 c出 c进 1 0 1 0 1 0
a进 b进 b出 a出 c进 c出 1 1 0 0 1 0
发现在栈为空的时候不能进行出栈请求,所以 入栈数<=出栈数,对于每一位来说前面元素都应该符合该条件。
设f(n) 是出栈顺序的数量,f(0) = 1,f(1) = 1,f(2) = 2,f(3) = f(0)*f(2) + f(1)*f(1) + f(2)*f(0) =5
设f(3)中三个元素a b c,有三个不同的位置1 2 3,
a在1 : f(0)*f(2) 它前面0个,后面两个
a在2 :f(1)*f(1)
a在3 :f(2)*f(0)
以此类推f(4) = ......
递推公式:
该递推关系的解为:
h(n)=C(2n,n)/(n+1) (n=1,2,3,...)
未用公式的解决方案(没有计算大数,并且内存超了。。):
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class Main{
static List<int[]> alist = new ArrayList<int[]>();
public static void main(String[] args){
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int n = in.nextInt();
int[] list = new int[2*n];
for (int i = 0; i < n; i++) {
list[i] = 1;
}
qpl(list,0,2*n);
int all = 0;
for (int i = 0; i < alist.size(); i++) {
int i1 = 0;
int i0 = 0;
for (int j = 0;j <alist.get(i).length;j++) {
if (alist.get(i)[j] == 1) {
i1++;
}else {
i0++;
}
if(i0 > i1) {
break;
}
}
if (i1 == i0 && i1 == n) all++;
}
System.out.println(all);
}
}
public static void qpl(int[] list, int min, int max) {
if (min == max) {
int[] temp = Arrays.copyOf(list, list.length);
alist.add(temp);
return;
}
for (int i = min; i < max; i++) {
if (isswop(list, min, i)) {
continue;
}
int temp = list[i];
list[i] = list[min];
list[min] = temp;
qpl(list, min+1, max);
temp = list[i];
list[i] = list[min];
list[min] = temp;
}
}
private static boolean isswop(int[] list, int min, int i) {
if (i > min) {
for (int j = min; j < i; j++) {
if (list[j] == list[i]) return true;
}
}
return false;
}
}
可执行方案:
import java.math.BigInteger;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
while (in.hasNext()) {
int n = in.nextInt();
BigInteger h = BigInteger.valueOf(1);
for (int i = 1; i <= n; i++) {
h = h.multiply(BigInteger.valueOf(4*i-2)).divide(BigInteger.valueOf(i+1));
}
System.out.println(h);
}
}
}
注意点:大数BigInteger的使用方法
要先乘再除,因为先除会产生误差
有重复元素的全排列问题
public static void qpl(int[] list, int min, int max) {
if (min == max) {
int[] temp = Arrays.copyOf(list, list.length);
alist.add(temp);
return;
}
for (int i = min; i < max; i++) {
if (isswop(list, min, i)) {
continue;
}
int temp = list[i];
list[i] = list[min];
list[min] = temp;
qpl(list, min+1, max);
temp = list[i];
list[i] = list[min];
list[min] = temp;
}
}
private static boolean isswop(int[] list, int min, int i) {
if (i > min) {
for (int j = min; j < i; j++) {
if (list[j] == list[i]) return true;
}
}
return false;
}