扔了一晚上的鸡蛋,找出来了第一次扔鸡蛋的最佳地点

http://blog.csdn.net/joylnwang/article/details/6769160

先给大家看看大神写的扔鸡蛋问题。所有的原理,DP实现都在,不赘述。大家好好学习,天天向上。

我想分享的是:

第一次扔地点的最佳地点的递归找法:(自己的测试都过了,希望大家都来查错;想按照大神的意思,找出所有的分界点,即找出扔各个鸡蛋的碎或没碎太困难啦,啥时候想到再分享给大家)

贴代码解释:

#include<cstdio>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;

int steps=0;

const int maxn=100;
const int maxm=100;
int drop[maxn][maxm];
int Max;
int before;

int Dropping(int n,int m)//跑一次记忆化DP,找到最优值,保存各个中间过程
{
	if (n==1) return drop[n][m]=m;
	if (n>=m) return drop[n][m]=pow(2,m)-1;
	if (drop[n-1][m-1]==0) Dropping(n-1,m-1);
	if (drop[n][m-1]==0) Dropping(n,m-1);
	return drop[n][m]=Dropping(n-1,m-1)+1+Dropping(n,m-1);
}

int findans(int n,int m)//找出当前最大值的第一个测试点!!
{
	int ans;
	if (n==1)//处理第一种情况
	{
		for(int i=before+1;i<=Max;i++)
				printf("%d%c",i,i==Max?'\n':' ');
	}
	else if (n<m)//处理递归分解的情况
	{
		ans=Max-drop[n][m-1];//用Max去减是因为我要算的是前面的累加和是多少
		before=ans; //before记录的是上一次的分点在哪儿
		printf("%d",ans);
		if (Max-ans)//如果ans==Max了,说明已经把鸡蛋扔到顶层了
		{
			printf(" ");findans(n,m-1);
		}
		else printf("\n");
	}
	else//处理n=m时候的情况,每次往后找,相当于区间二分
	{
		if (n>0)
		{
			ans=before+pow(2,m-1);//before记录的是上一次的分点在哪儿
			before=ans;
			printf("%d",ans);
			if (Max-ans)
			{
				printf(" ");
				findans(n-1,m-1);
			}
			else printf("\n");
		}
	}
}

int main()
{
	int n,m;
	//n=2,m=8;
	memset(drop,0,sizeof(drop));
	scanf("%d%d",&n,&m);
	printf("%d\n",Dropping(n,m));
	Max=drop[n][m];
	before=0;
	findans(n,m);
	return 0;
}
/*
	这其实只例举了正好D[n,m]的情况,
	其实,这个第一次扔鸡蛋的分案完全适用于:D[n,m-1]<k<=D[n,m]的所有情况
	原因解释:
	无非就是把后面的几个完整区间压缩小了而已啊!
*/ 
时间: 2024-10-21 21:13:33

扔了一晚上的鸡蛋,找出来了第一次扔鸡蛋的最佳地点的相关文章

大楼扔鸡蛋问题(动态规划)

题目链接:poj 3783 题意分析: 经典题,小白书上的一道例题,4+2出了这道原题,我愣是以为是数学题,最后也没做出来.题意是这样的,给你N个鸡蛋(硬度一样),让你测鸡蛋的硬度,测量的方法就是从某栋M层的楼的某一层X上把鸡蛋扔下来,如果鸡蛋碎了,代表他的强度小于X:如果没碎,则强度大于等于X.我们要做的就是不断的从楼上把鸡蛋扔下来,直到找到某一层楼X,从这一层楼扔下来鸡蛋不碎掉,从X+1层扔下来鸡蛋碎掉,那么鸡蛋的强度就是X.如果在M层扔下来鸡蛋也不碎掉,那么鸡蛋的强度为M.问题是,用N个鸡

扔鸡蛋问题详解(Egg Dropping Puzzle)

http://blog.csdn.net/joylnwang/article/details/6769160 经典的动态规划问题,题设是这样的:如果你有2颗鸡蛋,和一栋36层高的楼,现在你想知道在哪一层楼之下,鸡蛋不会被摔碎,应该如何用最少的测试次数对于任何答案楼层都能够使问题得到解决. 如果你从某一层楼扔下鸡蛋,它没有碎,则这个鸡蛋你可以继续用 如果这个鸡蛋摔碎了,则你可以用来测试的鸡蛋减少一个 所有鸡蛋的质量相同(都会在同一楼层以上摔碎) 对于一个鸡蛋,如果其在楼层i扔下的时候摔碎了,对于任

扔鸡蛋问题具体解释(Egg Dropping Puzzle)

经典的动态规划问题,题设是这种: 假设你有2颗鸡蛋,和一栋36层高的楼,如今你想知道在哪一层楼之下,鸡蛋不会被摔碎,应该怎样用最少的測试次数对于不论什么答案楼层都可以使问题得到解决. 假设你从某一层楼扔下鸡蛋,它没有碎,则这个鸡蛋你能够继续用 假设这个鸡蛋摔碎了,则你能够用来測试的鸡蛋降低一个 全部鸡蛋的质量同样(都会在同一楼层以上摔碎) 对于一个鸡蛋,假设其在楼层i扔下的时候摔碎了,对于不论什么不小于i的楼层,这个鸡蛋都会被摔碎 假设在楼层i扔下的时候没有摔碎,则对于不论什么不大于i的楼层,这

[CareerCup] 6.5 Drop Eggs 扔鸡蛋问题

6.5 There is a building of 100 floors. If an egg drops from the Nth floor or above, it will break. If it's dropped from any floor below, it will not break. You're given two eggs. Find N, while minimizing the number of drops for the worst case 这道题说有10

扔鸡蛋

Description Jzj要来做一个经典的实验:测试鸡蛋壳的坚硬程度. Jzj正好处于N层高的摩天大楼中,所以通过从某一楼层向下扔鸡蛋来测试鸡蛋壳的坚硬程度. Jzj有M个鸡蛋,所有的鸡蛋硬度都一样.如果鸡蛋从第L层摔下去没有碎,而在L+1层摔碎了,那么称鸡蛋的硬度是L.嗯,反正jzj不喜欢吃鸡蛋,所以不用担心浪费的问题.大楼共有N层高,如果在N层还没有摔碎,就认为硬度是N:如果在第1层就碎了,硬度为0. 虽然jzj不喜欢吃鸡蛋,但是jzj的好朋友yk特别喜欢吃鸡蛋.为了帮好朋友保护可怜的小

称3次,找出坏鸡蛋

有十二个鸡蛋,其中有一个是坏的(重量与其余鸡蛋不同),现要求用天平称三次,称出坏的那个鸡蛋 准备工作:将十二个鸡蛋编号,1.2.3......11.12.分为三组,1.2.3.4为第一组,5.6.7.8为第二组,9.10.11.12为第三组.其中,Time = ?表示这是第?次称. 分析:取第一组.第二组,分别放置在天平两端,两种情况:平衡,不平衡(Time = 1) ♦ if (平衡):这8个鸡蛋都是好的,取3个(1.2.3)出来,和剩下4个中的任意3个(假设是9.10.11),将这两组分别放

由2个鸡蛋从100层楼下落到HashMap的算法优化联想

题目: 有一栋楼共100层,一个鸡蛋从第N层及以上的楼层下落会摔破,在第N层以下的楼层不会摔破,给你两个鸡蛋,设计方案找出N,并且保证在最坏的情况下,最小化鸡蛋下落的次数.(鸡蛋没有摔破是可以重复利用的) 在这里,熟悉HashMap的底层实现的同学可能会想到,这里给你两个鸡蛋其实是给你两次机会做测试,第一次机会可以联想到通过HashCode的值来作为数组的分组存储依据,第二个鸡蛋则是让你在LinkList中遍历用的.即两次的操作,一次分组,一次遍历,通过两次操作即能确保找出那个层数N.但是这里略

(算法)扔棋子

题目: 1.有一个100层高的大厦,你手中有两个相同的玻璃围棋子.从这个大厦的某一层及更高的层扔下围棋子就会碎,用你手中的这两个玻璃围棋子,找出一个最优的策略(扔最少的次数),来得知那个临界层面. 2.如果大厦高度是N层,你有K个棋子,请问最少需要扔几次可以知道得临界层? 思路: 1.推导 这里不推倒,直接给出结论,具体推导参考:http://blog.csdn.net/jiaomeng/article/details/1435226 首先选择第x层扔第一个棋子q1: 如果棋子碎了,则在1~x-

算法题--扔棋子

题目如下:“有一个100层高的大厦,你手中有两个相同的玻璃围棋子.从这个大厦的某一层扔下围棋子就会碎,用你手中的这两个玻璃围棋子,找出一个最优的策略,来得知那个临界层面.“先说下扩展:n层k个球 这道题有一个dp解,因存在递归.假设第一次扔在第r层,碎了就在1~r之间寻找,此时还剩k-1个球:没碎就在r+1~n之间寻找,还剩k个球. 代码如下: 1 #include <iostream> 2 #include <fstream> 3 #include <sstream>