1. 程式人生 > >第九屆藍橋杯省賽(4)-- 測試次數

第九屆藍橋杯省賽(4)-- 測試次數

4.標題:測試次數

 

x星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。

各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之後才允許上市流通。

 

x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。

 

如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。

特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。

如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n

 

為了減少測試次數,從每個廠家抽樣3部手機參加測試。

 

某次測試的塔高為1000層,如果我們總是採用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?

 

請填寫這個最多測試次數。

 

注意:需要填寫的是一個整數,不要填寫任何多餘內容。

方法一:保證平均測試次數相同,例如兩個玻璃球,100層樓。

1+2+。。。。n >= 99  n解得為14

第一個球測試的樓層 14層 14+13層 14+13+12層 。。。層,前面的樓層間隔比後面的樓層間隔多一層,保證總測試次數相同。

方法二:dp

a[i][j] 代表i部手機 j層在最優策略下,最壞情況下測試的次數

dp方程:a[i][l] = min(a[i][l],1+max(a[i-1][m-1],a[i][l-m]));

程式碼:

#include<stdio.h>
#include<string.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
int main() {
	int phone_num = 3,high = 1000;
	int a[4][1005];
	memset(a,0,sizeof(a));
	// 邊界 一層樓 測試一次就可以 
	for(int k=1;k<=phone_num;k++) {
		a[k][1] = 1;
	}
	// 邊界 一部手機 測試樓層次數 
	for(int j=1;j<=high;j++) {
		a[1][j]=j;
	} 
	for(int i=2;i<=phone_num;i++) {
		for(int l=2;l<=high;l++) {
			a[i][l] = a[i][l-1]+1;
			for (int m=2;m<=l;m++) {
				a[i][l] = min(a[i][l],1+max(a[i-1][m-1],a[i][l-m]));
			} 
		}
	}
	printf("%d",a[3][1000]);
}