一座大楼有层,地面算作第0层,最高的一层为第N层。已知棋子从第0层掉落肯定不会摔碎,从第i层掉落可能会摔碎,也可能不会摔碎()。给定整数N作为楼层数,再给定整数K作为棋子数,返回如果想找到棋子不会摔碎的最高层数,即使在最差的情况下扔的最小次数。一次只能扔一个棋子。
[要求]
时间复杂度在最坏情况下为
输入两个数N, K
输出一个数表示答案。
10 1
10
因为只有1棵棋子,所以不得不从第1层开始一直试到第10层,在最差的情况下,即第10层是不会摔坏的最高层,最少也要扔10次
3 2
2
先在2层扔1棵棋子,如果碎了,试第1层,如果没碎,试第3层
105 2
14
第一个棋子先在14层扔,碎了则用仅存的一个棋子试1~13层
若没碎,第一个棋子继续在27层扔,碎了则用仅存的一个棋子试15~26层
若没碎,第一个棋子继续在39层扔,碎了则用仅存的一个棋子试28~38层
若没碎,第一个棋子继续在50层扔,碎了则用仅存的一个棋子试40~49层
若没碎,第一个棋子继续在60层扔,碎了则用仅存的一个棋子试51~59层
若没碎,第一个棋子继续在69层扔,碎了则用仅存的一个棋子试61~68层
若没碎,第一个棋子继续在77层扔,碎了则用仅存的一个棋子试70~76层
若没碎,第一个棋子继续在84层扔,碎了则用仅存的一个棋子试78~83层
若没碎,第一个棋子继续在90层扔,碎了则用仅存的一个棋子试85~89层
若没碎,第一个棋子继续在95层扔,碎了则用仅存的一个棋子试91~94层
若没碎,第一个棋子继续在99层扔,碎了则用仅存的一个棋子试96~98层
若没碎,第一个棋子继续在102层扔,碎了则用仅存的一个棋子试100、101层
若没碎,第一个棋子继续在104层扔,碎了则用仅存的一个棋子试103层
若没碎,第一个棋子继续在105层扔,若到这一步还没碎,那么105便是结果
保证最后答案在long long范围内
这题关键是在变换思路,将原问题中的最少需要几次变换成,拥有i个棋子,扔j次最多可以测试出多少楼高,所以状态转移方程可以写成:
dp[i][j] = d[i][j-1] + dp[i-1][j-1] + 1
n, k = map(int, input().split()) l = [i for i in range(n+1)] if k == 1: print(n) else: sign = False floor = 2 while True: tmp = [1] * n for i in range(2,n+1): tmp[i] = l[i-1] + tmp[i-1] + 1 if floor != k and tmp[i] >= n: break if floor == k and tmp[i] >= n: sign = True print(i) break if sign: break floor += 1 l = tmp
Python解法超时了,但是一样的解法用C就不超时 emmmmm