动态规划-测试次数

写在前面:

这是第一次写算法题,说的更详细点,第一次写关于动态规划的。学过数据结构、算法的,可能都知道,动态规划挺不简单的,对于我,一个算法小白来说,难度有多大呢?题都看不懂,以此呢,开始写一些关于动态规划的文章,一方面呢,对自己的了解程度有一个认识,其次呢,也是做一个笔记吧,每天呢,进步一点点就好了

废话不多说,我们直接来看题目吧

标题:测试次数
x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。
x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。
如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n
为了减少测试次数,从每个厂家抽样3部手机参加测试。
某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?
请填写这个最多测试次数。
注意:需要填写的是一个整数,不要填写任何多余内容。

上面这个题呢,是2018年蓝桥杯B组的一题,不知道大家看了题有啥反映,我一看,直接就懵了,先不说别的,就那个最佳策略最坏运气,是啥意思呢???根本下不去手啊,有人可能或说,这题是道动态规划题?不知道你信不信,反正刚开始我不信,那这道题就不能入手了么?当然不会,你品,你细品。。。

我们先来模拟一下什么是最佳策略最佳运气
分析

大家一定要仔细看上面的分析,了解什么是最坏运气,什么是最佳策略,从图里面的例子可以看出,我们对三种情况,从一楼开始摔,从二楼楷书摔,从三楼开始摔,都在保证最坏运气的前提下,我们得到了结果,分别是3次,2次,3次,显然,当测试次数为2时,我们就称为最佳策略。。。

喝一杯凉白开,我们再来看题目,要求求得最佳策略,分析题,我们大家,最佳策略与什么有关?和手机有关么?显然无关,与手机的数目有关,与层数有关,所以呢,我们可以来画一个表格,就像这样

分析

看到这,我想大多数应该都蒙了吧,怎么突然来了个t(?)(?),怎么有的标黄了呢,大家仔细的想一想,当层数是4层的时候,我们可以分别从第1、2、3、4层去分析,分别计算出它所需的次数,我们先来解释下标黄色的单元代表什么意思,它代表在从第i(1=<i<=4)时计算耐摔指数的最坏运气,对这四种情况,他们在最坏运气下的次数分别为3次、3次、3次,4次,那如何体现最佳策略呢,当然就是在这些值中取最小值,即3

接下来,我们来详细说一下t(?)(?)是啥意思,之所以放到这说,第一个呢,向让大家多思考一下,如果你已经想清楚了,恭喜你,我比你菜多了,t(?)(?),第一个?代表手机的数目,第二个?代表层数,我们看上图里面的例子,第一种情况,当在第一层摔摔手机后,手机是好的(如果这儿还不明白为啥是好的,请再多看看前面的),这时我们还有两部手机,还有三层没有测试,不正好对应表格中当手机数为2,层数为3层的情况么???,这儿非常重要,一定要想明白,我们再来看一个例子,当从第四层开始扔手机的时候,手机摔坏了(如果这儿还不明白为啥是好的,请再多看看前面的),我们这时只有一部手机了,还有三层没测试呢,不正好是t(1)(3)么?,所以,这就是本题的递推公式,这里,我不会直接把递推公式写出了,大家先自己琢磨琢磨,我们来看代码

#include <iostream>
using namespace std;
#include <math.h>
#include <climits>
const int N = 1000;//塔的层数
int t1[N+1];//当手机为一部时的情况 
int t2[N+1];//当手机为两部时的情况
int t3[N+1];//当手机为三部时的情况

int main(int argc, char** argv) {
	//当手机为一部时
	for(int i=1;i<=N;i++){
		t1[i]=i;
	} 
	//当手机为两部时
	for(int i=1;i<=N;i++){
		int ans = INT_MAX;
		for(int j=1;j<=i;j++){
			//好  坏
			ans = min(ans,max(1+t2[i-j],1+t1[j-1]));
		}
		t2[i]=ans;
	}
	//当手机为三部时
	for(int i=1;i<=N;i++){
		int ans = INT_MAX;
		for(int j=1;j<=i;j++){
			//好  坏
			ans = min(ans,max(1+t3[i-j],1+t2[j-1]));
		}
		t3[i]=ans;
	}
	cout<<t3[1000]<<endl; 
	return 0;
}

大家看了上面代码之后,我想递推公式也应该差不多了吧,在这儿呢,我们可以简单写一下
递推公式
字数比较多,排版也比较随意,感谢大家能看到这儿,如果有什么不足,或者有更好的方法来解这道题,欢迎大家留言区留言哦,

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只学弱狗!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值