Balls poj3783 (dp, worst-case optimal solution)

poj3783 Balls

Title:

 There are some eggs, we now want to know the hardness of these eggs. And now there is a very tall building, and we are now going to test the hardness of eggs on this building. The hardness of each egg is the same, and the hardness of the egg is defined as: if the egg falls from the mth layer without cracking, but falls from the m+1th layer and breaks, then the hardness of the egg is m. If an egg breaks in the experiment, it will be lost forever. We now have n eggs. So in the worst case, how many experiments do we need to do at least?

Ideas:

  This is a classic dp problem. Suppose dp[n,m] is the i-th floor. When there are k eggs to find the minimum number of tests that meet the conditions,
an egg will be dropped from the i-th floor. If it is broken, there is still m−1 eggs. In order to determine the safe position of the lower floor, dp[i−1,m−1] times (subproblems) are needed; if not broken, there are n−i floors above, and dp[n −i,m] times (sub-problem, the minimum number of judgments required for the upper n−i floor of an entity n-floor is actually the same as the minimum number of judgments required for an entity n−i floor)

Here, because we are looking for the best solution for the worst case,
when traversing each floor, we should choose the maximum value of the two cases in each floor, and then compare the minimum value.

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#define __int128 LL

using namespace std;

typedef long long ll;

const int mod = 1e9;
const int maxn = 1e3 + 5;
const int INF = 1e9 + 7;

int dp[maxn][60];//dp[i][j]:表示在 i 层楼 还有 j 个鸡蛋的最小判断次数

void DP(int n,int m)
{
    
    
    memset(dp,0,sizeof dp);
    //对于一个鸡蛋,只能一层一层的试
    for(int i = 1; i <= n; i++){
    
        
        dp[i][1] = i;
    }
    //对于只有一层,肯定有且仅有一次
    for(int i = 1; i <=m; i++){
    
    
        dp[1][i] = 1;
    }
    for(int i = 1; i <= n; i++){
    
    
        for(int j = 2; j <= m; j++){
    
    
            dp[i][j] = i;//初始最坏结果是i次
            for(int k = 1; k <= i; k++) dp[i][j] = min(dp[i][j] ,max(dp[k - 1][j - 1] + 1,dp[i - k][j] + 1));
        }
    }
}

int main()
{
    
    
    int t;
    cin>>t;
    while(t--){
    
    
        int op,n,m;
        cin>>op>>m>>n;
        DP(n,m);
        cout<<op<<' '<<dp[n][m]<<endl;
    }
    return 0;
}```

Guess you like

Origin blog.csdn.net/CUCUC1/article/details/109407814