一本通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
",dp(n,m)); 
	}
	return 0;
}

原文地址:https://www.cnblogs.com/57xmz/p/14419861.html