完美世界2019春实习笔试

实习编程题,方法比较low,很naive,如有错误,请见谅,望及时指正。

Question #1

有n个小朋友,每个小朋友都有自己的座位。恰好每个小朋友都坐错座位,方式有多少种?

要求算法的复杂度较低,且不考虑整形溢出,其中n<=66。

输入:

第一行:一个自然数,表示小朋友的个数。

输出:

一个整数,表示符合条件的坐法有多少种。

输入范例:

4

输出: 

9

分析一波:可以采用分治法的思想。对于小朋友A的位置,剩下有n-1个小朋友都可以坐。若把坐在A小朋友位置上的称作B,那么对于小朋友A此时有两种选择:1.A坐在B的位置上,2.A不坐在B的位置上。对于情形1,剩下的n-2个小朋友看作是一个n=n-2的子问题;对于情形2,A不坐在B位置上,那么我们把位置B现在看作本是A的位置,A不可以坐在这,那就成了一个n=n-1的子问题。基于这种想法,首先想到的是递归的做法:

def f(n):
    if n == 1:
        return 0
    if n == 0:
        return 1
    return (n - 1) * (f(n-1) + f(n-2))


if __name__ == "__main__":
    print(f(4))

但是呢,这种比较暴力的纯递归方法会计算大量的重复子问题,导致复杂度及其高,所以需要寻求更加优化的方法。例如:动态规划。

def f(n):
    res = [0 for _ in range(n + 1)]
    res[1] = 0
    res[2] = 1
    for i in range(n-2):
        t = i + 3
        res[t] = (t - 1) * (res[t-1] + res[t-2])
    return res[n]


if __name__ == "__main__":
    print(f(4))

Question #2

小明参加数学竞赛,假设小明都会做,但是时间有限,每个题目花费的时间和题目的分数不同,小明需要在考试的有限时间内获得最高的得分。

输入:

第一行:题目的数量

第二行:每个题的分数,空格隔开

第三行:每个题花费的时间,空格隔开

第四行:本场考试的总时间

输出:

小明得的最高分

输入范例:

5

5 4 3 5 2

2 2 3 5 1

10

输出: 

16

分析一波:最简单的0-1背包问题。

def f(num, score, time, total_t):
    res = [[0 for _ in range(total_t + 1)] for _ in range(num + 1)]
    for i in range(num + 1):
        if i == 0:
            continue
        for j in range(total_t + 1):
            if j == 0:
                continue
            if j < time[i]:
                res[i][j] = res[i - 1][j]
            else:
                res[i][j] = max(res[i - 1][j], res[i - 1][j - time[i]] + score[i])

    return res[num][total_t]


if __name__ == "__main__":
    print(f(5, [0, 5, 4, 3, 5, 2], [0, 2, 2, 3, 5, 1], 10))

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值