Chernobyl’ Eagle on a Roof URAL - 1223[递推dp]

Chernobyl’ Eagle on a Roof URAL - 1223[递推dp]_第1张图片Chernobyl’ Eagle on a Roof URAL - 1223[递推dp]_第2张图片

题目:有n个鸡蛋,m层的楼房,假设所有鸡蛋的坚硬程度都是一样的,要做实验确定楼层E,在楼层E扔下一个鸡蛋鸡蛋没碎,在E+1或者更高的楼层扔下一个鸡蛋,鸡蛋就会碎,假设一个鸡蛋没有碎,就会用到下一次实验,求最坏情况下的最少实验次数,就能确定E的; 

题解:最坏情况下的最小值,dp[i][j]表示有i个鸡蛋,j层楼的最坏情况下的最少实验次数,状态转移方程如下:

dp[i][j] = min_{\{1\leqslant k\leqslant j\}} \begin{Bmatrix} max(dp[i-1][k-1], dp[i][j-k]) + 1 \end{Bmatrix}

具体解释:枚举楼层k,如果实验鸡蛋碎了,那么就用i - 1个鸡蛋去进行k - 1层实验的最坏情况+1;否则,那么就用i个鸡蛋去进行k - m层实验的最坏情况+1;

代码:

#include
#include
#define ll long long
using namespace std;
const int maxn = 1e3+7;


int n, f, dp[maxn][maxn];

int main() {
    #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
        long _begin_time = clock();
    #endif
    while(~scanf("%d%d", &n, &f)){
        memset(dp, 0, sizeof(dp));
        if(n == 0&&f == 0) break;
        int c = ceil(log2(f+1));
        if(n>=c) {
            printf("%d\n", c);
            continue;
        } 
        for(int i = 1; i <= f; i++) dp[1][i] = i;
        for(int i = 2; i <= n; i++) {
            for(int j = 1; j <= f; j++) {
                dp[i][j] = dp[i-1][j-1] + 1;
                for(int k = 1; k < j; k++) {
                    dp[i][j] = min(dp[i][j], max(dp[i-1][k-1], dp[i][j-k]) + 1);
                }
            }
        }
        printf("%d\n", dp[n][f]);
    }
    #ifndef ONLINE_JUDGE
        long _end_time = clock();
        //printf("time = %ld ms\n", _end_time - _begin_time);
    #endif
    return 0 ; 
}

 

你可能感兴趣的:(DP专题,动态规划)