鸡蛋掉落/玻璃球与楼层高度 动态规划

*题目:

你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑。
每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。
你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。
每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。
你的目标是确切地知道 F 的值是多少。
无论 F 的初始值如何,你确定 F 的值的最小移动次数是多少?*

**

思路:

**
//dp[k][m] 的含义是k个鸡蛋 移动m次最多能够确定多少楼层
//第一个鸡蛋扔完,碎了剩下能确定的dp[k - 1][m - 1]下边的楼层,没碎剩下能确定的dp[k][m - 1]上 边的楼层,+1本层
//dp[k][m] = dp[k - 1][m - 1] + dp[k][m - 1] + 1
//dp[k][1]=1;dp[1][m]=m

/ 可直接给出解
   if (K == `1 || N` == `1 || N` == 2) 
     {
        return N;
     }

//由于 m 为所求值,创建二维数组时,无法确定 m 值,因此,以 一维数组 代替 二维数组 进行计算;则每一个座标的值等于 当前位置值 + 前一位置值 + 1

 // 初始化首列(第一步)
int *dp = new int[K + 1];
  for (int index = 1; index <= K; index++) 
  {
 dp[index] = 1;
 }

 // 从第二步开始计算
int m = 2;
while (true) 
{
      for (int k = K; k > 1; k--) 
    {  // 从后向前计算,以免 k-1 位置过早被新值覆盖,导致后续计算错误。
    //相当于还带有m-1,dp[k][m] = dp[k - 1][m - 1] + dp[k][m - 1] + 1,形式上省略了
    dp[k] = dp[k] + dp[k - 1] + 1;
    }

  // 判断是否满足条件
  if (dp[K] >= N) 
  {
    return m;
  } 
  else 
  {
    dp[1] = m;  // 覆盖首位值
    m++;  // 进入下一步
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章