藍橋杯第18屆第四題——測試手機(dp、思維)

測試手機

x星球的居民脾氣不太好,但好在他們生氣的時候唯一的異常舉動是:摔手機。
各大廠商也就紛紛推出各種耐摔型手機。x星球的質監局規定了手機必須經過耐摔測試,並且評定出一個耐摔指數來,之後才允許上市流通。
x星球有很多高聳入雲的高塔,剛好可以用來做耐摔測試。塔的每一層高度都是一樣的,與地球上稍有不同的是,他們的第一層不是地面,而是相當於我們的2樓。
如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
特別地,如果手機從第1層扔下去就壞了,則耐摔指數=0。
如果到了塔的最高層第n層扔沒摔壞,則耐摔指數=n
爲了減少測試次數,從每個廠家抽樣3部手機參加測試。
某次測試的塔高爲1000層,如果我們總是採用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數呢?
請填寫這個最多測試次數。

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


題意

①、耐摔指數:如果手機從第7層扔下去沒摔壞,但第8層摔壞了,則手機耐摔指數=7。
②、測試手機個數:每個廠家抽樣3部手機參加測試。換句話說,在將3部手機摔壞後,一定要測試出該廠家手機耐摔指數。
③、題目設定情景:我們總是採用最佳策略,在最壞的運氣下最多需要測試多少次才能確定手機的耐摔指數。

誤區:二分選層

在題目理解上錯誤的話,很容易以爲該題每次測試都選擇在未測試層數中,居中的那層。
eg:在1000層爲測試層數內,選擇第500層作爲開始測試的層數。這樣我們就會得到在塔高爲1000層的情況下,測試10次就能得到手機耐摔指數,這個結果是有問題的,不符合題目設定情景。

在題目設定情景下,若選擇以第500層作爲開始測試的層數,能測試10次就得到手機耐摔指數嗎?

測試次數 測試層數 手機測試結果
1 500
2 250
3 125
4 67 (沒手機可以測試)

通過上面的表格,可以看出在題目給定的情景下,不能通過二分的方式來查找手機耐摔指數。

解題思路:遞推

①、有一部手機可用於測試的情況:
在最壞運氣的情況下,有多少層就應該測多少次。
eg:假設測試的最高層數爲10層,那麼最佳策略應該是測10次。
②、有兩部手機可用於測試的情況:
將1層 ~ n層都作爲起始測試點,每次得到最多的測試次數test。(在測試結果好與壞中取最多的測試次數)
在由1層 ~ n層得到的n個test中,將最小的test作爲用兩部手機測試n層最佳策略。
③、有三部手機可用於測試的情況:
同求有兩部手機可用於測試的情況大同小異。
④、得到結果:
在最壞運氣、採用最佳策略的情況下,用三部手機測試最高層數爲1000層時的測試次數。
具體請將文字結合代碼一同理解,效果更佳。

#include<bits/stdc++.h>
using namespace std;
int dp[1010][4];
int main()
{
	//初始化 
	dp[1][2]=1; 
	dp[1][3]=1;
	for(int i=1; i<=1000; i++)
	dp[i][1]=i;
	
	//遞推 
	for(int k=2; k<=3; k++)		//一共有k部手機  
	{
		for(int sum=2; sum<=1000; sum++)	//求第sum層最壞運氣測試次數 
		{
			int min_=1001;
			
			//最壞運氣條件下,尋找k部手機在第sum層的最佳策略(測試次數最少) 
			for(int i=1; i<=sum; i++)		//假設從i層開始測試 
			{
				int good=1+dp[sum-i][k];	
				//假設測試結果:好			(餘剩sum-i層未測) 
				//i層最壞運氣測試次數 = 1 + k部手機在第sum-i層最壞運氣測試次數
				
				int bad =1+dp[i-1][k-1];	
				//假設測試結果:壞			(餘剩i-1層未測)
				//i層最壞運氣測試次數 = 1 + (k-1)部手機在第i-1層最壞運氣測試次數
				
				//從第i層開始測試,最壞運氣條件下,測試次數max_
				int max_=max(good, bad);
				
				//判斷從i層開始測試得到最壞運氣測試次數是否比min_更小 
				min_=min(max_, min_);
			}
			
			//k部手機在第sum層最壞運氣測試次數
			dp[sum][k]=min_;
		}
	}

	cout<<dp[1000][3];
	return 0;
}

總結

這道題目邏輯會相對複雜一些。
兩個根本問題:什麼情況下是最壞運氣?怎麼做纔是最佳策略?
另外很容易就掉入二分選層的誤區,認爲二分就是最佳策略。

希望能夠將自己的一些學習經驗分享給有需要的人。
我是小鄭,一個堅持不懈的小白。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章