一本通1300 鸡蛋的硬度

题目传送门

思路

首先你要看懂这个样例是什么意思,然后这个题就很简单了。其实就是一层楼一层楼的试,如果鸡蛋碎了,你就少了一个鸡蛋。如果没碎,那就从剩下的楼层再尝试。设\(f_{i,j}\)为手中还有\(i\)个鸡蛋,还有\(j\)层楼需要尝试的最多次数,那么转移就分两种情况进行讨论:\(1.\)如果碎了,那么就由\(f_{i-1,j-1}+1\)(你扔这一次还要算上一次)转移而来。\(2.\)如果没碎,那么就由\(f_{i,j-k}+1\)转移而来,其中\(k\)是枚举在那一层楼扔下去的。但是我们可以发现,如果直接三层循环,我们在枚举到\(f_{i,j}\)的时候可能不知道\(f_{i,j-k}\)的值,这样就没办法转移了。

于是,这时候就请出了记忆化搜索来完成这件事,再枚举一下边界情况,这个题就过了。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
int n,m;
int f[110][110];
int dp(int i,int j){
	if(f[i][j]<2147483647) return f[i][j];
	if(i==1) return f[i][j]=j;
	if(i==0) return f[i][j]=1000000000;
	if(j==1) return f[i][j]=1;
	if(j==0) return f[i][j]=0;
	for(int k=1;k<=j;k++){
		f[i][j]=min(f[i][j],max(dp(i-1,k-1),dp(i,j-k))+1);
	}
	return f[i][j];
}
int main()
{
	while(cin>>m>>n){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				f[i][j]=2147483647;
			}
		}
		printf("%d\n",dp(n,m)); 
	}
	return 0;
}

posted @ 2021-02-20 11:17  徐明拯  阅读(224)  评论(0编辑  收藏  举报