[一本通]鸡蛋的硬度

题意:

测试一批鸡蛋的硬度,有(m)个鸡蛋能用,鸡蛋碎了就不能继续用了,没碎可以捡回来,现在已知鸡蛋的硬度在([1,n])以内或者不会碎。求最坏情况下最小的检测次数。

题解:

这道题在学校ACM课程选拔的时候见过。当时以为是分块或者二分,结果是动态规划。现在回想起来是的,分块和二分目的是优化时间,而非求得最优解,要想最优解还得看贪心和动态规划啊。

知道是动态规划了就好解决了,重点是状态划分。
只有一个鸡蛋的时候,高度为(n)要测试(n)次。

(m)个鸡蛋的时候,假如在高度(k)测试了一次。
如果鸡蛋碎了,接下来就是用(m-1)个鸡蛋测试(k-1)个高度。
如果鸡蛋没碎,接下来就是用(m)个鸡蛋测试(n-k)个高度。
最坏情况就是两个取最大值。

(f[n][m])表示(n)高度下,有(m)个鸡蛋,最少测试几次。
(f[n][m] = min(max(f[k-1][m-1], f[n-k][m])+1))

#include <bits/stdc++.h>
#define Mid ((l + r) >> 1)
#define lson (rt << 1)
#define rson (rt << 1 | 1)
using namespace std;
int read(){
	char c; int num, f = 1;
	while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0';
	while(c = getchar(), isdigit(c)) num = num * 10 + c - '0';
	return f * num;
}
int n, m, f[19][109];
signed main()
{	
	memset(f, 0x3f, sizeof(f));
	for(int i = 1; i <= 100; i++) f[1][i] = i; f[1][0] = 0;
	for(int i = 2; i <= 10; i++) {
		f[i][1] = 1; f[i][0] = 0;
		for(int j = 1; j <= 100; j++) {
			for(int k = 1; k <= j; k++) {
				f[i][j] = min(f[i][j], max(f[i - 1][k - 1], f[i][j - k]) + 1);
			}
		}
	}
	while(cin >> n >> m) cout << f[m][n] << endl;
	return 0;
}
原文地址:https://www.cnblogs.com/onglublog/p/14377081.html