扔鸡蛋问题

来源:互联网 发布:大作家智能写作软件 编辑:程序博客网 时间:2024/04/30 11:48

扔鸡蛋问题


  • 问题来源:
    经典的动态规划问题,题设是这样的:
    如果你有2颗鸡蛋,和一栋36层高的楼,现在你想知道在哪一层楼之下,鸡蛋不会被摔碎,应该如何用最少的测试次数对于任何答案楼层都能够使问题得到解决。
    如果你从某一层楼扔下鸡蛋,它没有碎,则这个鸡蛋你可以继续用
    如果这个鸡蛋摔碎了,则你可以用来测试的鸡蛋减少一个
    所有鸡蛋的质量相同(都会在同一楼层以上摔碎)
    对于一个鸡蛋,如果其在楼层i扔下的时候摔碎了,对于任何不小于i的楼层,这个鸡蛋都会被摔碎
    如果在楼层i扔下的时候没有摔碎,则对于任何不大于i的楼层,这颗鸡蛋也不会摔碎
    从第1层扔下,鸡蛋不一定完好,从第36层扔下,鸡蛋也不一定会摔碎。

解法:

#include <stdio.h>#define max(x,y) ((x)>(y))?(x):(y)using namespace std;int dp[10][50];int main(int argc, const char * argv[]) {    int egg;   //给定鸡蛋数量    int floor; //给定楼梯层数    while (scanf("%d%d", &egg, &floor)!=EOF) {        if (egg==0||floor==0) {            return -1;        }        for (int i=1; i<=floor; i++) {            dp[1][i] = i;        }        for (int i=2; i<=egg; i++) {            for (int j=1; j<=floor; j++) {                if (i>j) {                    dp[i][j] = dp[i-1][j];                }                else{                    int min = 65535;                    for (int k=1; k<=floor; k++) {   //遍历从第一层到第k层落下鸡蛋,选择刚开始从不同层数落下鸡蛋时能确定阶层数的最小值。                        int k_drop = max(dp[i-1][k-1], dp[i][j-k]);   //开始时从第k层落下鸡蛋的话,至少需要多少步能够确定摔破鸡蛋的层数                        if (k_drop<min) {                            min = k_drop;                        }                    }                    dp[i][j] = min+1;  //加1,是因为包括第k层落下鸡蛋。                }            }        }        int ans = dp[egg][floor];        printf("%d\n", ans);    }    return 0;}

注意:具体解释看笔记本,后续补充到博客。

0 0