算法训练 未名湖边的烦恼

本文探讨了一种解决冬季滑冰租鞋排队问题的算法,通过递归或动态规划方法,计算在有限冰鞋数量下,如何安排还鞋与租鞋者排队,以避免租鞋尴尬情况的发生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

  每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩。
  每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个。现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的尴尬场面。(两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种排法)

输入格式

  两个整数,表示m和n

输出格式

  一个整数,表示队伍的排法的方案数。

样例输入

3 2

样例输出

5

数据规模和约定

  m,n∈[0,18]
  问题分析

 

考点:递归 递推 

问题分析: 这是一种类似汉诺塔问题的题目首。先要保证换鞋的人m多于借鞋的人n。否则,无论怎么排序,都是会出现无鞋可借的尴尬局面。
所以,首先判断(m>n),否则返回0,表示没有方法来排序。
之后,当还鞋的人数n为0 的时候,这时候无论怎么排序都是一种方法,所以这时候函数返回的是1;

 

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
int func(int n,int m){
	if(n<m) return 0;
	if(m==0) return 1;
	return func(n-1,m)+func(n,m-1); 
}
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	printf("%d\n",func(n,m));
	return 0;
} 

PS:这里的return fun(m-1,n)+fun(m,n-1)——前面的fun(m-1,n)意思是还鞋子的一个人站在最前面,之后剩下的人再接着排序,fun(m,n-1) 意思是借鞋子的人站在最后面,剩下的再接着排序。

 


 

OR——DP法

dp[i][j] 表示当前有i个人还鞋,j个人借鞋时有多少种排法。需要注意的是,最开始先放还鞋的,并且在排的队列中当前位置之前借鞋的人数不能超过还鞋的人数,不然就借不到鞋了。

当i=j时,dp[i][j]=dp[i][j-1] 

当i>j时,当前位置随便放借鞋还是还鞋都可以, 

dp[i][j]=dp[i-1][j-1]+dp[i][j-1]

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
int dp[20][20];
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		dp[i][0]=1;
		for(int j=1;j<=m;j++){
			if(i>j) 
				dp[i][j]=dp[i][j-1]+dp[i-1][j];
			else if(i==j)
				dp[i][j]=dp[i][j-1];
		}
	}
	printf("%d\n",dp[n][m]);
	return 0;
} 

 

或者用一种接近递归思想的非递归算法:

 

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int dp[20][20];
int main() {
	int m,n;
	memset(dp,0,sizeof(dp));
	for(int i=1; i<=18; i++) {
		dp[i][0] = 1;
		for(int j=1; j<=i; j++)
			dp[i][j] = dp[i-1][j] + dp[i][j-1];
	}
	scanf("%d%d",&m,&n);
	printf("%d\n",dp[m][n]);
	return 0;
}

 


 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值