蓝桥杯第九届B组C++省赛 测试次数 【动态规划】

x星球质监局规定手机需经耐摔测试并评定耐摔指数。此次测试塔高1000层,抽样3部手机。要确定在最佳策略、最坏运气下的最多测试次数。解题需考虑不同手机数量和楼层情况,通过尝试所有策略找出最佳策略,可采用递推或递归求解。

标题:测试次数

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

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

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

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

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

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

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

解题思路

17分的题啊同志们!!!还是个填空题,能让你随随便便做出来???

题目要求的是在在总是采用最佳策略的情况下,最坏运气下最多需要测试的次数,先来想这样的问题,假如我们只有一部手机,我们要测试它的耐摔度,只能从第一层开始摔,即n层楼在最坏运气下最多需要测试n次,以dp[ i][ j]表示j部手机i层楼的情况,dp[ i][ 1] = i;  如果不是一部手机呢?  首先面对的问题是什么是最优策略,我不知道,(我知道你也不知道,否则你就不来我看详解瞎扯了),不知道咋办?所有策略一个个试呗,得到测试次数最小的那个就是最优策略了。假如现在一共有i层楼j部手机,我在第k层(k<=i)摔手机(此时我有j个手机),要么摔碎了,要么没摔碎,摔碎了就去前k-1层,用j-1部手机测试,没摔碎就去后(i-k)层,用j部手机测试,最坏情况下就是这两者测试次数的最大值,这是第一次在第k层摔的策略下的最多次数。我要是第一次不在第k层,在第k+1,k+2 ··层呢?这就是不同策略了,最佳策略最坏运气下(最多需要测试的次数)即为所有策略所需测试最多次数 的 最小值 (有点绕,好好想)。 明白了这点递推或者递归(需要记忆化)就行了。

代码

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int dp[1001][4];	// dp[i][j]表示一共i层楼,有j个手机,以题目要求的最多测试次数 
    
	memset(dp,0,sizeof dp);
    for(int i=1;i<=1000;i++)
    	dp[i][1] = i;	// 只有一个手机只能从第一层开始向高层n摔,最运气就是在第n层摔碎或者不碎 
	
	int Max = 0; 
	for(int j=2;j<=3;j++) {	// 算j部手机的情况时,需要用到 <= (j-1)部手机的结果 
		for(int i=1;i<=1000;i++) {	// 算i层时,需要用到前i-1层的结果 
			dp[i][j] = 1+dp[i-1][j];	// 这是dp[i][j]的最大值
	                /*
		 	 *用i-1层楼确定的最小次数+1,多摔上一次肯定能确定出i层楼(现在最高即i层)
			 *用求i-1层时用的最优策略下最少用多少次。   
			 */
			for(int k=2;k<=i;k++) 	// 枚举所有策略 
				dp[i][j] = min(dp[i][j],1+max(dp[k-1][j-1],dp[i-k][j]));
		}
	} 
	printf("%d\n",dp[1000][3]);
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值