鸡蛋的硬度

题目大意:

有一个傻X无聊的公司用扔鸡蛋的办法测试鸡蛋硬度,求最坏情况要扔几次,只能从第一层扔到第n层,如果这个鸡蛋在第n层没碎,在n+1层碎了,这个鸡蛋的硬度就是n。然后多事的小A又想着用二分,结果想到自己都烦还在想。(无聊的小A)然后又让你帮他解决问题。

【输入】
输入包括多组数据,每组数据一行,包含两个正整数n和m(1≤n≤100,1≤m≤10),其中n表示楼的高度,m表示你现在拥有的鸡蛋个数,这些鸡蛋硬度相同(即它们从同样高的地方掉下来要么都摔碎要么都不碎),并且小于等于n。你可以假定硬度为x的鸡蛋从高度小于等于x的地方摔无论如何都不会碎(没摔碎的鸡蛋可以继续使用),而只要从比x高的地方扔必然会碎。

对每组输入数据,你可以假定鸡蛋的硬度在0至n之间,即在n+1层扔鸡蛋一定会碎。

【输出】
对于每一组输入,输出一个整数,表示使用最优策略在最坏情况下所需要的扔鸡蛋次数。
【输入样例】
100 1
100 2
【输出样例】
100
14

解题思路:

其实就是记忆化搜索
先要处理好边界问题吧:
if (m==1) return f[n][m]=n; //如果只有一个鸡蛋,那只能扔n次,不然直接碎了就没机会了。
if (m==0) return f[n][m]=0; //没有鸡蛋扔个皮皮虾
if (n==1) return f[n][m]=1; //只有一层楼还用说吗?就算这个鸡蛋的硬度是10^1000000,还是只能测出来是1。
if (n==0) return f[n][m]=0; //楼都没有扔个皮皮虾。
好了,边界处理好了
重点来了
你们最想要的动态转移方程

f[n][m]=min(f[n][m],1+max(dp(i1,m1),dp(ni,m)));//i=1..n f [ n ] [ m ] = m i n ( f [ n ] [ m ] , 1 + m a x ( d p ( i − 1 , m − 1 ) , d p ( n − i , m ) ) ) ; / / i = 1.. n

源程序奉上:

#include<cstdio>  
#include<cstring>  
#define inf 0x3f
#define r(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n,m,ans,f[101][101];   
int max(int x,int y)
{
    return x>y?x:y;//等于 if(x>y)return x;else return y;
}  
int min(int x,int y)
{
    return x>y?y:x;//等于 if(x>y)return y;else return x;
}  
int dp(int n,int m)  
{  
    if (f[n][m]<inf) return f[n][m];//如果找过了就退,不用重复再找(记忆化搜索)
    if (m==1) return f[n][m]=n;
    if (m==0) return f[n][m]=0;
    if (n==1) return f[n][m]=1;
    if (n==0) return f[n][m]=0;//这四条边界处理上面讲过了
    r(i,1,n)
     f[n][m]=min(f[n][m],1+max(dp(i-1,m-1),dp(n-i,m)));//在最坏情况下找最优解
    return f[n][m];//返回
}
int main()  
{
    memset(f,inf,sizeof(f));  //赋初值,因为是找最坏情况中的最优解所以赋值很大
    while (scanf("%d%d",&n,&m)==2)//读入
     printf("%d\n",dp(n,m));//直接进入dp,输出返回值
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值