第九届蓝桥杯个人赛省赛(软件类)C++B组试题第四题

一【题目描述】

标题:测试次数

x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。

x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。

如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n

为了减少测试次数,从每个厂家抽样3部手机参加测试。

某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?

请填写这个最多测试次数。

注意:需要填写的是一个整数,不要填写任何多余内容。


 

二【解题思路】

  • 首先看到这个题目就知道问题是求3部手机,1000层楼在最坏的运气下需要测试多少次才知道耐摔指数,即采用最佳策略,最少测试多少次可以知道耐摔指数(嘻嘻,摔手机可真有钱啊)。
  • 我们假设最佳的测试次数是k次(i部手机,j层楼),那么从k层开始摔,就有两种情况:第一种就是摔碎了,那么我们之后就要找到是哪一层摔碎的,所以就需要继续摔1~k-1层;第二种就是没有摔碎,那么继续摔k+1~j层(即j-k层,这里我们只看楼层数)。
  • 我们发现上面的规律是依据上一个的数据得到下一个的,那么就想到了动态规划中状态转移方程,有上面规律就有假设最佳次数是D[i][j] = max(D[i-1][k-1],D[i][j-k]) + 1。
  • 我们知道最差的情况就是每一层都摔一次,既然用到了最佳策略,那么D[i][j]次数就小于等于最坏的情况,所以式子可以写成D[i][j] = min(D[i][j],max(D[i-1][k-1],D[i][j-k]) + 1)。所以这里我们就开始写代码吧。(有用手写计算的,当是两个情况的时候比较好计算,但是3个情况的时候就比较麻烦,所以这里就直接按照动态规划思路来吧)。
  • 参考:https://blog.csdn.net/wolinxuebin/article/details/47057707

三【解题步骤】

#include<bits/stdc++.h>
using namespace std;
int CoutPhone(int phone,int floor)
{
	int D[5][1005];//定义数组,空间可以稍微大一点
	for(int i=1;i<=phone;i++)
		for(int j=1;j<=floor;j++)
			D[i][j] = j;//最坏情况:i部手机j层楼最坏次数就是j次 
	for(int i=2;i<=phone;i++)
		for(int j=1;j<=floor;j++)
			for(int k=1;k<j;k++)//第k层开始 
				D[i][j] = min(D[i][j],max(D[i-1][k-1],D[i][j-k])+1);
	return D[phone][floor]; 
 } 
int main()
{
	cout<<"最佳次数是:"<<CoutPhone(3,1000)<<endl; 
	return 0; 
}

所以最后的答案就是:19

扫描二维码关注公众号,回复: 9457155 查看本文章

四【总结】

  这次用到了动态规划状态转移方程,分析好其中的规律(其中的界限也很重要),找到方程就可以写出代码计算。当数字很小的时候就可以用手算。继续冲鸭!如有误,请指出哦,谢谢。

发布了93 篇原创文章 · 获赞 193 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43919400/article/details/103702055