(算法)扔棋子

题目:

1、有一个100层高的大厦,你手中有两个相同的玻璃围棋子。从这个大厦的某一层及更高的层扔下围棋子就会碎,用你手中的这两个玻璃围棋子,找出一个最优的策略(扔最少的次数),来得知那个临界层面。

2、如果大厦高度是N层,你有K个棋子,请问最少需要扔几次可以知道得临界层?

思路:

1、推导

这里不推倒,直接给出结论,具体推导参考:http://blog.csdn.net/jiaomeng/article/details/1435226

首先选择第x层扔第一个棋子q1:

如果棋子碎了,则在1~x-1之间通过另一个棋子q2来从下到上依次试探哪一层为临界层面;

如果棋子没碎,则选择在x+(x-1)=2x-1层继续扔棋子q1:

  如果棋子碎了,则在x+1~2x之间通过另一个棋子q2来从下到上依次试探哪一层为临界层面;

  如果棋子没碎,则选择在x+(x-1)+(x-2)=3x-3继续扔棋子q1;

。。。。。。

如果棋子一直没碎,那么棋子q1会一直扔到某一层大于或等于100即停止:x+(x-1)+(x-2)+(x-3)+...+2+1>=100,即求x*(x+1)/2的最小值,使之满足>=100,求解得到x=14.

即:

先从14层扔(碎了试1-13,需1+13-1+1=14次)
再从27层扔(碎了试15-26,需2+26-15+1=14次)
再从39层扔(碎了试28-38,需3+38-28+1=14次)
再从50层扔(碎了试40-49,需4+49-40+1=14次)
再从60层扔(碎了试51-59,需5+59-51+1=14次)
再从69层扔(碎了试61-68,需6+68-61+1=14次)
再从77层扔(碎了试70-76,需7+76-70+1=14次)
再从84层扔(碎了试78-83,需8+83-78+1=14次)
再从90层扔(碎了试85-89,需9+89-85+1=14次)
再从95层扔(碎了试91-94,需10+94-91+1=14次)
再从99层扔(碎了试96-98,需11+98-96+1=14次)
最后从100层扔(根据题意一定会碎,也可以不扔了,需11次)

最坏情况下扔14次。

2、动态规划

假设dp[i][j]表示有i层,j个棋子时得到临界层,需要的最少次数。

初始状态:

当i=1,即只有1层,dp[1][j]=1;(j>0)

当j=1,只有1个棋子,dp[i][1]=i;(i>0)

状态转移方程:

dp[i][j]=min(max(dp[k-1][j-1],dp[i-k][j])+1)  (0<k<i)

解释:当选择在第k层扔棋子时,此时有两种情况,考虑的最坏情况,因此选择其大者。

棋子碎了,则棋子数减1,并在1~k-1层试探,此时次数为dp[k-1][j-1]+1;

棋子未碎,则棋子数不变,在k+1~j层试探,此时次数为dp[j-k][j]+1;

代码:

route[i][j]表示当有i层j个棋子的下一步选择哪一层扔棋子,通过route可以记录每次扔棋子的楼层。

参考:http://blog.csdn.net/taylor_tao/article/details/7084467?reload

#include <iostream>
#include <vector>
#include <stdlib.h>

using namespace std;

#define LAYERS 101
#define CUPS 3

int main()
{
    vector<vector<int> > dp(LAYERS,vector<int>(CUPS));
    vector<vector<int> > route(LAYERS,vector<int>(CUPS));

    for(int i=1;i<LAYERS;i++){
//      dp[i][0]=0;
        dp[i][1]=i;
    }

    for(int i=1;i<CUPS;i++){
//      dp[0][i]=0;
        dp[1][i]=1;
        route[1][i]=0;
    }

    for(int j=2;j<CUPS;j++){
        for(int i=2;i<LAYERS;i++){
            dp[i][j]=i;
            route[i][j]=0;
            for(int k=1;k<i;k++){
                int mini=max(dp[k-1][j-1],dp[i-k][j])+1;
                route[i][j]=mini<=dp[i][j]?k:route[i][j];
                dp[i][j]=mini<dp[i][j]?mini:dp[i][j];
            }
        }
    }
    cout << dp[LAYERS-1][CUPS-1] <<endl;
    return 0;
}
时间: 2024-10-10 21:06:27

(算法)扔棋子的相关文章

算法题--扔棋子

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

计算机科学精彩帖子收集

inux源码 LXR 源自"the Linux Cross Referencer",中间的"X"形象地代表了"Cross".与 Source Navigator 类似,它也是分析阅读源代码的好工具.不同的是,它将源代码借助浏览器展示出来,文件间的跳转过程成了我熟悉的点击超链接动作. http://lxr.linux.no/   LXR安装过程简介 linux手册 http://linux.die.net/man/ Linux每周新闻 http:/

图论①

2750: [HAOI2012]Road Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 651  Solved: 302[Submit][Status][Discuss] Description C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它们包含的道路序列不同.我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路

用算法帮上海大妈垃圾分类,扔错罚款!长点心吧你

从7月1日起,上海市将正式实施<上海市生活垃圾管理条例>.条例规定,个人混合投放垃圾今后可最高罚200元,单位混装混运,最高可罚至5万元,而且违规还将会列入征信,堪称“史上最严垃圾分类措施”. 面对志愿者的大妈的灵魂拷问,一时间“你是什么垃圾”成为年轻人之间最流行的日常用语. 其实,在我国垃圾分类的举措要从2000年开始,但效果并不理想,我国每年的生活垃圾仍然以5%增长.上海邀请志愿者大妈帮忙监督也是无奈之举. 怎么帮助大妈们解决 “你是什么垃圾”的问题呢? 在物联网.人工智能快速发展的这几年

常见算法和例题

第3章  算法与程序设计模块 3.1  算    法 算法是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或多个操作. 常用的算法:列举了穷举搜索.递归.回溯.递推.模拟.分治.贪心.深度优先搜索.广度优先搜索等几种较为常用的算法,没有做过多的描述,一旦给出具体描述,容易使内容加深,产生严重学科取向的引导,符合教育部普通高中课程方案的特点,对于这些必需的方法和思想,关键不在于学生能不能,而在于教师是否想到,是否有过关注,引发学生对系统方法和思想的思考,重视建立编程思想,

丢棋子问题 ——(动态规划)

题目描述 ? 一座大楼一共有0~N层,地面算第0层,最高一层为第N层.已知棋子从第0层掉落肯定不会摔碎,从第i层掉落可能回摔碎,也可能不会摔碎(1<=i<=N).给定整数N作为楼层数,再给定整数K作为棋子数,返回如果想找到棋子不会摔碎的最高层数,即使在最差的情况下仍的最少次数.一次只能仍一个棋子. 例子 N=10, K=1. 返回10.因为只有1颗棋子,所以不得不从第一层开始一直试到第十层,最差情况要扔10次. N=3, K=2. 返回2.现在第2层仍1颗棋子,如果碎了,试第1层:如果没碎,试

算法 排序NB二人组 堆排序 归并排序

参考博客:基于python的七种经典排序算法     常用排序算法总结(一) 序前传 - 树与二叉树 树是一种很常见的非线性的数据结构,称为树形结构,简称树.所谓数据结构就是一组数据的集合连同它们的储存关系和对它们的操作方法.树形结构就像自然界的一颗树的构造一样,有一个根和若干个树枝和树叶.根或主干是第一层的,从主干长出的分枝是第二层的,一层一层直到最后,末端的没有分支的结点叫做叶子,所以树形结构是一个层次结构.在<数据结构>中,则用人类的血统关系来命名,一个结点的分枝叫做该结点的"

回溯法 -数据结构与算法

1.回溯法算法思想: 定义: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 1.回溯法适用:有许多问题,当需要找出它的解集(全部解)或者要求回答什么解是满足某些约束条件的最优解时,往往要使用回溯法. 2.有组织的穷举式搜索:回溯法的基本做法是搜索或者有的组织穷尽搜索.它能避免搜索所有的可能性.即避免不必要的搜索.这种方

我的算法学习之路

关于 严格来说,本文题目应该是我的数据结构和算法学习之路,但这个写法实在太绕口--况且CS中的算法往往暗指数据结构和算法(例如算法导论指的实际上是数据结构和算法导论),所以我认为本文题目是合理的. 这篇文章讲了什么? 我这些年学习数据结构和算法的总结. 一些不错的算法书籍和教程. 算法的重要性. 初学 第一次接触数据结构是在大二下学期的数据结构课程.然而这门课程并没有让我入门--当时自己正忙于倒卖各种MP3和耳机,对于这些课程根本就不屑一顾--反正最后考试划个重点也能过,于是这门整个计算机专业本