java:未名湖边的烦恼(动态递归)

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));
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向上Claire

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值