标题:测试次数
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]);
}