java:未名湖边的烦恼
题目
问题描述
每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩。
每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个。现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的尴尬场面。(两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种排法)
输入格式
两个整数,表示m和n
输出格式
一个整数,表示队伍的排法的方案数。
样例输入
3 2
样例输出
5
数据规模和约定
m,n∈[0,18]
问题分析
我用的是非重复序列的全排列,就是说越界了,我搞不出来
package DFS;
import java.util.Scanner;
public class 未名湖边的烦恼 {
//private static StringBuffer s;
private static int m;
private static int n;
private static int q=m+n;
private static int ans=0;
private static boolean[] vis=new boolean[q];
private static int[] a;
public static void f(int k,int path[]){
if(k==q){
if(check(path)){
ans++;
return;
}
}
//生成不带重复元素的全排列
for(int i=0;i<q;i++){
//必须保证抓两个不同的数不同
//现在准备选取的元素和上一个元素相同,但是上一个元素还没被使用
if(i>0&&a[i]==a[i-1]&&!vis[i-1]){
continue;
}
if(!vis[i]){//当没有被访问过
vis[i]=true;//标记已访问过
path[k]=a[i];//将a[i]填入到path[k]中
f(k+1,path);//递归
vis[i]=false;//回溯
}
}
}
private static boolean check(int path[]) {
// TODO Auto-generated method stub
if(path[0]==-1)
return false;
else{
int sum=1;
for(int j=1;j<m+n;j++){
if(sum<0){
return false;
}else{
sum+=path[j];
}
}
}
return true;
/*int sum=0;
if(path[0]=='1')
sum++;
else
return false;
for(int i=1;i<m+n;i++){
if(sum>=0){
if(a[i]=='1')
sum++;
else
sum--;
}else{
return false;
}
}
return true;*/
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//这题就是重复元素的排序问题
Scanner sc=new Scanner(System.in);
m = sc.nextInt();
n = sc.nextInt();
a = new int[q];
//s = new StringBuffer();
for(int i=0;i<m;i++){
a[i]=1;
}
for(int i=m;i<q;i++){
a[i]=-1;
}
int path[]=new int[q];
f(0,path);
System.out.println(ans);
}
}
package DFS;
import java.util.Scanner;
public class 未名湖边的烦恼 {
//private static StringBuffer s;
private static int m;
private static int n;
private static int q=m+n;
private static int ans=0;
private static boolean[] vis=new boolean[q];
private static int[] a;
public static int f(int m,int n){
if(m<n)//当还鞋的小于借鞋的,此时方法就不对
return 0;
else if(n==0)//当没有借鞋的时候,就是还鞋的
return 1;//全都为1
else return f(m-1,n)+f(m,n-1);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//这题就是重复元素的排序问题
Scanner sc=new Scanner(System.in);
m = sc.nextInt();
n = sc.nextInt();
f(m,n);
System.out.println(f(m,n));
}
}