算法训练 未名湖边的烦恼( 每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩。   每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个)

问题描述

每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩。
  每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个。现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的尴尬场面。(两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种排法)
输入格式
  两个整数,表示m和n
输出格式
  一个整数,表示队伍的排法的方案数。
样例输入
3 2
样例输出
5
数据规模和约定
  m,n∈[0,18]

思路:

采用递归的方法简单易懂。
先要保证换鞋的人m多于借鞋的人n。否则,无论怎么排序,都是会出现无鞋可借的尴尬局面。
所以,首先判断(m>n),否则返回0,表示没有方法来排序。
之后,当还鞋的人数n为0 的时候,这时候无论怎么排序都是一种方法,所以这时候函数返回的是1;
这里的return fun(m-1,n)+fun(m,n-1)——前面的fun(m-1,n)意思是还鞋子的一个人站在最前面,之后剩下的人再接着排序,fun(m,n-1) 意思是借鞋子的人站在最后面,剩下的再接着排序。

代码呈上:

#include <stdio.h>
int fun(int n,int m)
{
    
    
	if(n<m) return 0;
	if(m==0) return 1;
	return fun(n-1,m)+fun(n,m-1); 
}
int main()
{
    
    
	int n,m;
	scanf("%d%d",&n,&m);
	printf("%d\n",fun(n,m));
	return 0;
}

运行示例
在这里插入图片描述

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 <stdio.h>
int main ()
{
    
    
	int dp[20][20];
	int m,n;
	int i,j;
	scanf("%d %d",&m,&n);
	for(i=1;i<=m;i++)
	{
    
    
		dp[i][0]=1;
		for(j=1;j<=n;j++)
		{
    
    
			if(i>j)
				dp[i][j]=dp[i-1][j]+dp[i][j-1];
			if(i==j)
				dp[i][j]=dp[i][j-1];
		}
	}
	printf("%d",dp[m][n]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45281807/article/details/105828399
今日推荐