完美世界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))

 

你可能感兴趣的:(刷题)