鸡蛋问题的分析与C++实现

 

说明:仅仅分享思想和代码设计方法,代码是用于验证和对照(对照是为了方便你检查你写的哪里有问题),我强烈建议你自己动手实现,我明确反对你直接用我的代码去写报告或其它目的。

参考了网上的教程http://blog.sina.com.cn/s/blog_6c813dbd0101bh98.html

原问题:为100楼,两个鸡蛋测试多少次,可以找到恰好鸡蛋碎的楼的问题。做个简单的转换,假设k次测试,两个鸡蛋最多能测试n楼。则问题求解就变为k为何值时,n大于100。

这个问题复杂度为O(1),因为指定了鸡蛋数量。因为对于n楼,你可以第一次扔在k楼,

此时如果碎了,你剩下的k-1测试和你的一个鸡蛋一楼一楼试,能找出结果。如果没碎,你还有两个鸡蛋,加k-1次机会,你第二次鸡蛋扔在k+k-1层,此时若碎了,你剩下的k-2测试和你的一个鸡蛋一楼一楼试,能找到结果。递推发现n=k+k-1+k-2+...1。所以就一个数学表达式的复杂度O(1).

证明:可证明采用这种方法两个鸡蛋能测试最多的楼层。采用数学归纳法。对于k=1次测试机会这显然成立。假设k=n,这种方法正确。令k=n+1。则第一次机会必然放在楼层n+1以下。假设放在n+1以上,则加入第一次鸡蛋碎了,剩下只能一楼一楼测了,那还剩余n次机会,就不能保证一定能找到原来会碎的楼层了。

拓展:所以为使用动态规划知识,原问题可更改为n个鸡蛋,k次测试,最多测试多少楼的问题。

参考上面的想法,得到递归表达式,这个想法由上面衍生,对于n个鸡蛋,k次机会,你可以第一次放在n-1个鸡蛋,k-1次机会的上方,如果蛋碎了,你能找到碎的楼层,如果没碎,则原问题转化为n个鸡蛋,k-1机会所测的高度加上你现在的高度。

然后递归式收敛情况,分两种,一个是你机会用完了,

一个是测得只剩下只有一只鸡蛋了,

分析:如果这个递归表达式n,k均不指定,那时间复杂度渐进确界为(n方),指定一个则为n,都指定为1。

回到原问题如果给定楼层高度,和鸡蛋数n。那么k得从小一个一个试出来。相当于k未指定,时间复杂度升了一个量级为n。(无论情况的好坏)

谈回指明鸡蛋数的情况:

空间复杂度,如果使用动态规划算法,则需要一个鸡蛋数*楼层高度得表,目的是为了不计算相同子问题。空间复杂度n方。

如果单纯使用递归,主要是递归工作栈的开销。

int egg(int n, int k)
{
	if (n == 1)
		return k;
	if (k == 0)
		return 0;
	return egg(n - 1, k - 1) + egg(n, k - 1) + 1;
}
int eggs(int n, int k)
{
	if (n == 1&&k!=0)
	{
		if (find(sss.begin(), sss.end(), k) == sss.end())
		{
			sss.push_back(k);
			a += k + 1;
			if (a < 50)
				cout << a << ' ';
		}
		return k;
	}
	if (k == 0)
		return 0;
	return eggs(n - 1, k - 1) + eggs(n, k - 1) + 1;
}
int main()
{
	int i, j;
	for(int i=1;i<8;++i)
	for (int leg = 50; leg <= 200; leg *= 2)
	{
		for ( j = 2; j <= 3; ++j)
		{
			cout << "楼数为" << leg << "鸡蛋数为" << j<<"的情况:" ;
			for (i = 1; egg(j, i) < leg; ++i);
			cout << "需要至少" << i << "次测试" << endl;
		}
	}
	cout << "当鸡蛋数为2,楼数为50的详细放蛋过程(假设蛋均未碎)为:" << endl;
	cout << "楼层:";
	eggs(2, 10);
	cout << endl;
	a = 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值