标题:测试次数
x星球的居民脾气不太好,但好在他们生气的时候唯一的异常举动是:摔手机。
各大厂商也就纷纷推出各种耐摔型手机。x星球的质监局规定了手机必须经过耐摔测试,并且评定出一个耐摔指数来,之后才允许上市流通。
x星球有很多高耸入云的高塔,刚好可以用来做耐摔测试。塔的每一层高度都是一样的,与地球上稍有不同的是,他们的第一层不是地面,而是相当于我们的2楼。
如果手机从第7层扔下去没摔坏,但第8层摔坏了,则手机耐摔指数=7。
特别地,如果手机从第1层扔下去就坏了,则耐摔指数=0。
如果到了塔的最高层第n层扔没摔坏,则耐摔指数=n
为了减少测试次数,从每个厂家抽样3部手机参加测试。
某次测试的塔高为1000层,如果我们总是采用最佳策略,在最坏的运气下最多需要测试多少次才能确定手机的耐摔指数呢?
看到这题我上来的想法就是直接用二分法 10次,想的有点天真。
这题用到的时动态规划,在之前对这类题的接触比较少,所以花费了较多的时间才弄懂``
首先需要对这题较为简单的数据进行列举:
横着是手机数,竖着是楼层数
当手机数为2,楼层为4时,应为需要最佳方案所以f(2,4)会有四种情况,分别是第一次分别取1,2,3,4次,没总情况又分为两种:手机摔坏或没摔坏的两种情况,所以有以下情况:
在第一层摔时:手机为好:f(2,4)=1+f(2,0)
为坏:f(2,4)=1+f(1,3)
在第二层摔时:手机为好:f(2,4)=1+f(2,2)
为坏:f(2,4)=1+f(1,1)
在第三层摔时:手机为好:f(2,4)=1+f(2,1)
为坏:f(2,4)=1+f(1,2)
在第四层摔时:手机为好:f(2,4)=1+f(2,0)
为坏:f(2,4)=1+f(1,3)
由上可以看出后面加的那个数在前面肯定出现过,找到了公式
代码思路:将每一层进行测试,分为手机摔后是好是坏找出每层的最大值在对所有最大值中找到其中的最大值
将所有的情况放在一个二维数组中,分别表示楼层数和手机数,,然后在里面再加一个for循环对每进行的情况进行分析。
代码`:
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int m=sc.nextInt();//手机数
int n=sc.nextInt();//楼层数
int arr[][]=new int [m+1][n+1];//记录没总情况
//当楼层为一时,只用摔一次
for(int i=1;i<=m;i++) {
arr[i][1]=1;
}
//当手机为1时,需要摔的次数为楼层数
for(int i=1;i<=n;i++) {
arr[1][i]=i;
}
for(int i=2;i<=m;i++) {
for(int j=2;j<=n;j++) {
for(int x=1;x<j;x++) {
int s=Math.max(1+arr[i][j-x], 1+arr[i-1][x-1]);
if(arr[i][j]==0) {
arr[i][j]=s;
}else {
arr[i][j]=Math.min(s, arr[i][j]);
}
}
}
}
System.out.println(arr[m][n]);
}
动态规划题:先对题目分析,对较为简单的数据找到规律,然后思考代码