`
kping
  • 浏览: 3254 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

算法的基本思想分析面试题

阅读更多
    有同学和我讲了一个这样的面试题目,你站在一个一百层的高楼上,每层楼都有自己的突出板子(相互不遮挡),你有两个弹弹球(材质完全一样),但是你不知道它最多能承受多少层楼的重力加速度后碎裂,如果没碎裂你可以准确的接住这丢下去的弹球(假设你是个高手)。现在要你用最少的测试次数来测试弹弹球最多能丢到第几层楼。
    一看到这个题,我们程序员第一反应当然是分治减治法,一般求最小,最少啊。估计没人会想要用穷举法吧(当然迫不得已也是有的)。好确定分治减治之后,一般定式会想到折半法,原因很简单,折半够利索。但是一想折半球不够啊,log2(100)可是比2大很多啊!!思路稍微混乱的人就怒了,nnd2个球要爷想什么办法啊!不过够冷静的人会想,怎么着比一个好吧,两个球如果折半至少节约50次了。(最倒霉的情况是弹弹球最多能丢到49层楼,第一个丢在50碎了,然后悲剧的穷举)在想想没碎是可以弹起来的呀,都已经把100分两段了,为什么不分小点,这样穷举也不用费劲啊。好就分4段看看行不,先把第一个球丢第25层,没碎继续,这样实验最多3次后知道是那段了,在穷举最多也就3+23次(第75层碎了,穷举)。既然这样不如再分小点,分10段好了,显然次数又在减少,然而什么时候最适合呢。有同学说在接近最好的时候都算下就出来了,显然这不是我们程序员应该有的思想,我们的想法是--好编程解决。
    然而问题又出来了,你如何设置你的编程思路呢,又或者题目发生变化是n层大楼你有r个玻璃球呢?这都是我们程序员需要解决的问题。
    假设在n层楼上对第r层抛一次(对应方程中的"+1"),会有两种情况发生:
    (1)玻璃球碎,说明在第1到第r层楼中必有一层为临界层,问题转化为一个子问题:求F(r,k-1)
    (2)玻璃球不碎,说明临界层在第r+1层到第n层这n-r层楼中,问题转化为子问题:求F(n-r,k)
    因为考虑的是最坏情况下抛球策略的所需测试次数的最小值,所以取这两种情况中的较大值,并遍历每一个可能的r,取其情况的最小值即得到F(n,k)。
    这样你发现--嘿嘿原来是一个动态规划的问题。我们知道动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。
    而动态规划最重要的是找到子问题和原问题建立的关系公式和边界。
    设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
    至此万事俱备只欠东风。接下来我们来看程序,以前实现过现在就偷懒在网上找个现成的了。
 #include <iostream>
 #include <fstream>
 #include <sstream>
 #include <string>
 #include <cmath>
 #include <iomanip>
 #include <vector>
 #include <deque>
 #include <list>
 #include <queue>
 #include <stack>
 #include <map>
 #include <algorithm>
 #include <limits>
 #include <utility>
 #include <ctime>
 #include <bitset>
 using namespace std;
 
 #define MAX_FLOOR 512
 #define MAX_BALL  100
 
 int dp(int n, int k)
 {
     if(k<1 || n<1) return -1;    //错误输入
 
     if(k==1) return n-1;        //去掉一些trivial case
     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 = numeric_limits<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 n,k;
     
     cin>>n>>k;
     cout<<dp(n, k)<<endl;
     
     return 0;
}

好运行下得出input: 100 2  output: 14
也许你会很神奇,这怎么得到的,好我们看具体数据:
第一个小球预计投下的楼层数为[14,27,39,50,60,69,77,84,90,95,99].
第二个小球需要测试的次数就为[13,12,11,10,9,8,7,6,5,4].
程序解决出来的方案是不是相当nice。
在换一种思考方式:
此问题关键是找到算法的公式,假设最坏情况需要n次,则归纳后得到:
在第一个小球不损害的情况下,第一次:n层,第二次:n+(n-1)层,依次类推到第n-1次:n+(n-1)+...+(n-(n-1)),由此,问题简化为:
1+2+3+...+n,在n大于多少时大于楼层数,得到结果为14。
其实有时候我们会发现,暴力方法是相当可爱的,有很多时候我们解决不了的时候,我们可以用暴力慢慢尝试,优秀的方法会慢慢浮出水面的。就像上面的动态规划问题,到了只有1个球的时候,唯一可行的就是暴力法,然而他却提供给我们一种局部策略。我们只要想到尽可能的少做暴力也就是编程之美咯。(一方浅见,大家勿喷!)
(第二次博客,不对请指教,建议请跟帖,谢谢!!!)   
分享到:
评论

相关推荐

    算法分析与设计+研究生复试+求职+面试题

    汇总了计算机研究生复试有关算法分析与设计各章节简答题,使用了易于口头表达的语言进行了总结。包括算法分析与设计基本概念及各章节问题回答。可供研究生复试或相关专业岗位面试使用。 1. 简述算法定义、属性及指标...

    微软算法与数据结构面试题答案

    在IT行业中,尤其是在软件开发和数据科学领域,算法与数据结构是至关重要的基础知识。微软作为全球顶级科技公司,其...通过深入学习和实践这些面试题,你可以增强自己的问题解决能力,为未来的职业发展打下坚实基础。

    Android面试算法题

    ### Android面试算法题知识点解析 #### 一、基础算法题:找出未放入数组中的两个数 **题目背景:** 在Android开发过程中,处理数组是非常常见的需求之一。此题旨在考察应聘者对基本数据结构(如数组)的理解以及...

    最快的排序算法 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹(详解)?,排序算法数据结构

    在解决腾讯算法面试题时,需要具备一定的解决思路和逻辑思维能力。通过分析问题的要求和限制条件,来设计出高效的解决方案。在这个问题中,需要通过一步一步的分析和推理,来确定最快的四匹马。 知识点7:C++语言的...

    算法设计与分析 习题测试数据答案

    通过解决这些问题,学习者可以逐步建立起对基本算法的理解,包括排序、搜索、动态规划、贪心策略等经典算法思想。而压缩包中的"ch1"文件很可能包含了这些题目的详细解答,供学习者参考和学习。 总的来说,熟练掌握...

    计算机算法设计与分析导论(Sara Baase,第三版)课后习题答案

    《计算机算法设计与分析导论》是Sara Baase撰写的一本经典教材,主要面向研究生层次的学生,旨在深入探讨算法的设计、分析以及其在计算机科学中的应用。这本书的第三版进一步更新了内容,以适应现代计算机科学的发展...

    算法设计与分析基础(Anany Levitin著,潘彦译,第三版)课后答案

    这本书主要涵盖了算法设计的基本方法、分析技巧以及如何利用这些工具解决实际问题。课后答案对于学习者来说是巩固理论知识,提升实践技能的重要参考资料。 首先,我们要理解算法设计的重要性。在计算机科学中,算法...

    2021最新大厂AI面试题:107题(含答案及解析).pdf

    明略科技AI岗位面试题中涉及到了熵、交叉熵的概念,熵是信息论中的一个基本概念,交叉熵则是衡量两个概率分布相似度的一种方法,常用于分类模型中。 knn(k近邻)算法是机器学习中最简单的算法之一,它的思想是通过...

    算法设计与分析基础(第3版) 原版

    该分类法站在通用问题求解策略的高度,对现有大多数算法准确分类,从而引领读者沿着一条清晰、一致、连贯的思路来探索算法设计与分析这一迷人领域。《算法设计与分析基础(第3版)》作为第3版,相对前版调整了多个章节...

    各类IT公司笔试面试题(数据结构算法)收集,很全很实用

    对于面试题和笔试题,你应该熟悉以下几种常见的问题类型: 1. 代码实现:例如,实现一个简单的排序算法或者设计一个特定功能的函数。 2. 逻辑分析:比如给出一段代码,让你分析其运行结果或者找出可能存在的问题。 3...

    算法分析设计课后题答案

    《算法分析设计课后题答案》是针对吕国英教授编著的《算法分析与设计》一书的习题解答,主要涵盖了第三章和第四章的内容。这两章在算法领域中至关重要,因为它们深入探讨了算法的基础理论和实践应用。 第三章通常...

    2020年精选50面试题及答案.rar

    这份名为"2020年精选50面试题及答案.rar"的压缩包文件,汇聚了2020年各大知名互联网公司,如阿里巴巴、百度、滴滴出行、华为、京东、腾讯、字节跳动、美团和中兴的面试题目及对应答案。这是一份非常宝贵的资料,对于...

    微软等公司数据结构与算法面试题库,共100题

    欢迎.txt文件可能是对题库的介绍或使用指南,可以帮助用户更好地理解和使用这些面试题。 对于没有积分或者无法直接下载资源的人,可以通过私信获取,这展示了资源共享和互助的精神。不过,重要的是,除了做题,还...

    文档面试题数据结构算法大全

    例如,快速排序是一种高效的排序算法,其基本思想是分治法,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的...

    前端八股文+vue+算法的基础面试题.zip

    本资料包"前端八股文+vue+算法的基础面试题.zip"显然是为了帮助准备前端面试,特别是涉及到Vue.js和算法知识的求职者所设计的。下面我们将详细探讨这些领域的重要知识点。 首先,"前端八股文"是指前端开发者需要...

    腾讯面试题 + 笔试题(全)

    《腾讯面试题与笔试题详解》 在求职的道路上,面试和笔试是必不可少的环节,尤其是对于技术人才来说,能够顺利通过大公司的面试更是彰显个人实力的重要标志。本压缩包包含两份珍贵的资料——“腾讯笔试题专辑(含...

    算法设计与分析C++语言描述(陈慧南版)书中程序

    《算法设计与分析C++语言描述》是由陈慧南编著的一本经典教材,它深入浅出地介绍了算法设计的基本思想、分析方法以及C++语言的实现技巧。这本书旨在帮助读者掌握如何用C++来有效地设计和分析算法,提升解决实际问题...

    Java常用算法手册

    首先介绍了算法概述,然后重点分析了数据结构和基本算法思想;接着,详细讲解了算法在排序、查找、数学计算、数论、历史趣题、游戏、密码学等领域中的应用;最后,列举了算法的一些常见面试题。书中知识点覆盖全面,...

Global site tag (gtag.js) - Google Analytics