蓝桥杯 算法训练 未名湖边的烦恼

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

第一种方法,递归

public static int f(int m, int n){
    if(m < n){
        //如果还鞋的小于借鞋的,那么该种排列不成立
        return 0;
    }else if(n == 0){
        //如果借鞋的为0,那么该种排列成立,不管后面是否还有多少还鞋的都没关系
        //你可能会说,后面有1个还鞋的和2个还鞋的是不一样的排列
        //但是你在整个递归中一定会把这2中情况都包括进去,所以不用去考虑这个
        //以及后面全是还鞋的,只能是一种情况,不用继续递归下去
        return 1;
    }
    //递归当前为借鞋或者还鞋
    return f(m, n - 1) + f(m - 1, n);
}

第二种方法,动态规划
dp[i][j]表示当前有i个人还鞋,j个人借鞋
那么 当i > j时,从上一步到这一步,既可能是借鞋,也可能是还鞋。
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
当i=j时,从上一步到这一步,一定是借鞋,如果是还鞋,那么上一步就是借鞋大于还鞋,这种情况是不可能的
dp[i[[j] = dp[i][j - 1];

    int[][] dp = new int[20][20];
    for(int i = 1; i <= m; ++i){
        dp[i][0] = 1;
        for(int j = 1; j <= i; ++j){
            if(i == j){
                dp[i][j] = dp[i][j - 1];
            }else{
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
            }
        }
    }
    System.out.println(dp[m][n]);

题目链接 http://lx.lanqiao.cn/problem.page?gpid=T303

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值