抛鸡蛋(玻璃球或围棋)
来源:互联网 发布:人教版课本同步软件 编辑:程序博客网 时间:2024/04/30 14:21
题目:一个100层的大厦,你手中有两个相同的鸡蛋(玻璃球或围棋)。从这个大厦的某一层扔下鸡蛋((玻璃球或围棋))就会碎,用你手中的这两个鸡蛋(玻璃球或围棋),找出一个最优的策略,来得知那个临界层面。
分析:这道题比较直观的想法是通过二分来寻找,但是二分的解法应该不是最优的。这里讨论通过动态规划的思路来求解。这里的最优策略指的是在这种策略下无论哪个临界层面在第几层,测试的次数都最少。设F(n,k)为用k个玻璃球来测试n层大厦的临界层的最少次数,状态转移方程如下:
F(n,k)=min{max{F(r,k-1), F(n-r,k)}+1, 1<=r<=n},边界条件:F(n,1)=n-1, F(1,k)=F(0,k)=0
状态转移方程可以这样来考虑,假设在n层楼中的第r层抛一次(对应方程中的"+1"),会有两种情况发生:
- (1)玻璃球碎,说明在第1到第r层楼中必有一层为临界层,问题转化为一个子问题:求F(r,k-1)
- (2)玻璃球不碎,说明临界层在第r+1层到第n层这n-r层楼中,问题转化为子问题:求F(n-r,k)
因为考虑的是最坏情况下抛球策略的所需测试次数的最小值,所以取这两种情况中的较大值,并遍历每一个可能的r,取其最小值即得到F(n,k)。实现代码如下:
#include<iostream>using namespace std;#define MAX_FLOOR 512#define MAX_BALL 100int dp(int n, int k){ if(k<1 || n<1) return -1; if(k==1) return n-1; if(n==1) return 0; int M[MAX_BALL][MAX_FLOOR]; int i,j,r; int temp, min; for(i=0;i<=k;i++) M[i][0]=M[i][1]=0; //F(1,k)=F(0,k)=0 for(j=2;j<=n;j++) M[1][j]=j-1; //F(n,1)=n-1 /* 状态转移方程: F(n,k)=min{max{F(r,k-1)+1, F(n-r,k)+1}, 1<=r<=n} */ for(i=2;i<=k;i++) for(j=2;j<=n;j++) { min = INT_MAX; for(r=1;r<=j;r++) { temp = max(M[i-1][r], M[i][j-r])+1; if(temp<min) min = temp; } M[i][j] = min; } return M[k][n];//F(n,k)}int main(){int floor=100;int ball=2;cout<<dp(floor,ball);}
- 抛鸡蛋(玻璃球或围棋)
- 抛鸡蛋(玻璃球或围棋)-优化版
- 动态规划解抛鸡蛋(玻璃球)问题
- 三个鸡蛋(玻璃球、围棋子)确定楼层问题公式推导
- 抛棋子抛鸡蛋抛围棋典型题解
- 抛玻璃球
- 腾讯抛玻璃球问题
- 玻璃球
- 围棋
- 围棋
- 围棋
- 围棋
- 围棋
- 围棋
- 围棋
- 鸡蛋
- 玻璃球问题
- google玻璃球
- 西南交大2011年第二次暑期集训比赛解题报告
- flash As3.0 学习笔记 第一课
- Tomcat 在win7 系统下tomcat-users.xml.new(拒绝访问)解决方法
- "java.lang.NoClassDefFoundError"错误——一个关于classpath设置的问题
- 虚拟机下安装ubuntu后root密码设置
- 抛鸡蛋(玻璃球或围棋)
- HDOJ 1085 Holding Bin-Laden Captive
- 配置java环境变量
- 在ubuntu 11.04下编写驱动程序
- 华丽分割线-----------------------------------------------------------------------------------------洒家又回来啦
- 如何把位图拷贝到剪贴板中
- HDOJ 1850 Being a Good Boy in Spring Festival解题报告
- 自学WPF--第七课StackPanel控件
- 游程编码之加密