鸡蛋的硬度
先想一个简单问题:只有两个鸡蛋的问题
-
两个软硬一样但未知的鸡蛋。有座100层的建筑,要你⽤用这两个鸡蛋确定 哪一层是鸡蛋可以安全落下的最⾼高位置。可以摔碎两个鸡蛋。
-
这是典型的动态规划问题。假设f[n]表示从n层楼找到摔鸡蛋不碎安全位置的最少判断次数。假设第⼀个鸡蛋第一次从第i层扔下,如果碎了了,就剩⼀个鸡蛋,为确定下⾯面楼层中的安全位置,必须从第⼀层挨着试,还需 要i−1次;如果不碎的话,上面还有n−i层,剩下两个鸡蛋,还需要f[n−i]次 (子问题,n层楼的上n-i层需要的最少判断次数和n-i层楼需要的最少判断 次数其实是⼀样的)。因此,最坏情况下还需要判断max(i-1,f[n-i])次。
-
状态转移方程:
f [ n ] = m i n 1 + m a x ( i − 1 , f [ n − i ] ) ∣ i = 1 … n f[n]=min1+max(i−1,f[n−i])|i=1…n f[n]=min1+max(i−1,f[n−i])∣i=1…n -
初始条件: f[0]=0(或f[1]=1)
推广成n层楼,m个鸡蛋
-
还是动态规划。假设f[n,m]表示n层楼、m个鸡蛋时找到摔鸡 蛋不碎的最少判断次数。则⼀个鸡蛋从第i层扔下,如果碎了,还剩m-1个鸡蛋,为确定下面楼层中的安全位置,还需要f[i−1,m−1]次(子问题);不碎的话,上面还有n-i层,还 需要f[n−i,m]次(子问题,n层楼的上的n-i层需要的最少判断次数和n-i层楼需要的最少判断次数其实是⼀样的)。
-
状态转移方程:
f [ n , m ] = m i n 1 + m a x ( f [ i − 1 , m − 1 ] , f [ n − i , m ] ) ∣ i = 1.. n f[n,m]=min1+max(f[i−1,m−1],f[n−i,m])|i=1..n f[n,m]=min1+max(f[i−1,m−1],f[n−i,m])∣i=1..n -
初始条件:f[i,0]=0(或f[i,1]=i),对所有i
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 110, M = 12;
/*
f[i][j] : 用j个鸡蛋,测量i层高楼,最优策略下最大测量次数
状态转移 :
1. 不用第j个鸡蛋 : f[i][j] = f[i][j - 1];
2. 用第j个鸡蛋 :
测量第k层楼,第j个鸡蛋是否碎
1) 没碎:f[i][j] = f[k - 1][j] + 1;
2) 碎:f[i][j] = f[i - k][j - 1] + 1;
*/
int f[N][M]; //
int main(){
int n, m;
while(cin >> n >> m){
// scanf("%d%d", &n, &m);
memset(f, 0, sizeof f);
for(int i = 1; i <= m; ++i) f[1][i] = 1;
for(int i = 1; i <= n; ++i) f[i][1] = i;
for(int i = 2; i <= n; ++i){
for(int j = 2; j <= m; ++j){
f[i][j] = f[i][j - 1];
for(int k = 1; k <= i; ++k){
f[i][j] = min(f[i][j], max(f[k - 1][j - 1], f[i - k][j]) + 1);
}
}
}
printf("%d\n", f[n][m]);
}
return 0;
}
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 110, M = 12;
/*
f[i][j] : 用j个鸡蛋,测量i次,最大的测量区间
状态转移 :
枚举扔鸡蛋的楼层k,类似dp1,
没碎测k楼以上,碎了测k楼以下,
那么能测的最大高度就是上下两部分加上第k层楼这一层
f[i][j] = f[i - 1][j] + f[i - 1][j - 1] + 1;
*/
int f[N][M]; //
int main(){
int n, m;
while(cin >> n >> m){
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= m; ++j){
f[i][j] = f[i - 1][j] + f[i - 1][j - 1] + 1;
}
if(f[i][m] >= n){
printf("%d\n", i);
break;
}
}
}
return 0;
}