[问答题]腾讯大楼扔玻璃珠 Golang 动态规划

[问答题]腾讯大楼扔玻璃珠

腾讯大厦有39层,你手里有两颗一抹一眼的玻璃珠。当你拿着玻璃珠在某一层往下扔的时候,一定会有两个结果,玻璃珠碎了或者没碎。大厦有个临界楼层。低于它的楼层,往下扔玻璃珠,玻璃珠不会碎,等于或高于它的楼层,扔下玻璃珠,玻璃珠一定会碎。玻璃珠碎了就不能再扔。现在让你设计一种方式,使得在该方式下,最坏的情况扔的次数比其他任何方式最坏的次数都少。也就是设计一种最有效的方式。

二分法?这过分简单了吧?

交卷后看评论才注意到玻璃珠只有两颗,让我们重新分析一下。

不失一般性,记 N N N为总楼层数, k k k为你丢玻璃珠的层数,用 F ( N ) F(N) F(N)表示在N层大楼上丢玻璃珠在最坏的情况下确定临街楼层最少的扔球次数。

那么我们在第k层丢玻璃珠之后:
①玻璃珠碎了,那么你只有一颗玻璃珠,为了确定邻接层,只能从 1 1 1开始一直丢直到 k − 1 k-1 k1层,加最开始丢的那一次,最坏的情况丢 k k k次;
②玻璃珠没碎,那么你就可以知道这个临界楼层在 ( k , N ] (k,N] (k,N]之间,并且你仍然拥有两颗玻璃珠,这相当于在一栋新的 N − k N-k Nk层大楼丢玻璃珠,最坏的情况就是 F ( N − k ) F(N-k) F(Nk),加最开始丢的那一次,共 F ( N − k ) + 1 F(N-k)+1 F(Nk)+1次。

在不同的楼层开始丢会得到不同的结果,我们取其中最小的一个,也就是最坏的情况下确定临街楼层最少的扔球次数。

package main

import "fmt"

func main() {
	F:=make([]int,40)
	F[1]=1
	for i:=2;i<40;i++{//大楼总楼层
		F[i]=i
		maz:=0
		for j:=1;j<i;j++{//丢珠子的楼层
			maz=max(j,F[i-j]+1)
			if maz<F[i]{
				F[i]=maz
			}
		}
	}
	fmt.Println(F)
}

func max( a,b int)int{
	if a>b {
		return a
	}else{
		return b
	}
}

输出:

[0 1 2 2 3 3 3 4 4 4 4 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 9 9 9]

最后建议腾讯开除这位没有公德心的员工,让我来。

你可能感兴趣的:(算法)