一、題目
小A每天都要吃a,b兩種面包各一個。而他有n個不同的面包機,不同面包機制作面包的時間各不相同。第i臺面包機制作a面包
需要花費ai的時間,制作b面包則需要花費bi的時間。
為能盡快吃到這兩種面包,小A可以選擇兩個不同的面包機x,y同時工作,并分別制作a,b兩種面包,花費的時間將是
max(ax,by)。
當然,小A也可以選擇其中一個面包機x制作a,b兩種面包,花費的時間將是ax+bx。
為能盡快吃到面包,請你幫小A計算一下,至少需要花費多少時間才能完成這兩種面包的制作。
輸入描述:
第一行一個正整數n,表示面包機的個數。
第二行n個正整數ai,表示面包機制作面包a的時間。
第三行n個正整數bi,表示面包機制作面包b的時間。
n ≤
100000
;
a,b ≤
100000
;
輸出描述:輸出一行一個正整數,表示需要花費的最少時間。
示例輸入
1
:
3
2
5
9
4
3
6
輸出:
3
示例輸入
2
:
3
2
5
7
2
8
6
輸出:
4
二、分析
該問題是關于如何計算制作兩種面包的最短時間,涉及到選擇單個面包機或者兩個不同的面包機來同時工作。先分析單面包機的情況,只需要遍歷所有面包機,找到制作 a 面包和 b 面包時間之和的最小值,這很容易,時間復雜度是 O(n)。但重點在于雙面包機的情況,因為直接窮舉所有可能的組合會導致時間復雜度高達 O(n2),對于大的 n 值來說不現實。因此,需要設計一個更高效的算法來找最小的 max(ax, by)。
可以考慮先對 a 和 b 的時間數組分別進行排序。然后使用兩個指針分別遍歷排序后的 a 和 b 數組,找到最優的組合。具體來說,先找到制作 a 面包最快和制作 b 面包最快的面包機,這樣可能得到一個較小的 max(ax, by)。也可以嘗試找出制作 a 面包最快的幾個面包機,然后在對應的 b 面包時間中找較小的值,或者找出制作 b 面包最快的幾個面包機,然后看對應的 a 面包時間。這種方法可能覆蓋大部分最優解的情況。
在代碼實現方面,讀取輸入的面包機數量和每個面包機的 a 和 b 時間。初始化兩個數組來存儲每個面包機的 a 和 b 時間。計算單個面包機情況下的最短時間,即找出所有面包機中 a 和 b 時間之和的最小值。然后處理兩個面包機的情況,嘗試找到兩個不同的面包機 x 和 y,使得 max(ax, by) 最小。為此,可以將 a 和 b 時間數組分別排序,然后使用兩個指針遍歷排序后的數組,找到可能的最優組合。最后,綜合單個面包機和兩個面包機的情況,輸出最小的時間值。
這種方法能夠較好地平衡時間和空間效率,確保在大數據量下程序也能高效運行。需要注意處理邊界情況,例如當只有一臺面包機時只能選擇單面包機的情況。通過這樣的分析和代碼實現,可以有效地解決題目要求的問題。
三、代碼
下面是一個完整的 Python 代碼示例,用于解決上述問題:
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))min_time = float('inf')# 單面包機情況
for i in range(n):total = a[i] + b[i]if total < min_time:min_time = total# 雙面包機情況
# 找到制作 a 最快的面包機對應的 b 時間
min_a = min(a)
index_min_a = a.index(min_a)candidate_b = b[index_min_a]
if max(min_a, candidate_b) < min_time:min_time = max(min_a, candidate_b)# 找到制作 b 最快的面包機對應的 a 時間
min_b = min(b)
index_min_b = b.index(min_b)candidate_a = a[index_min_b]
if max(candidate_a, min_b) < min_time:min_time = max(candidate_a, min_b)print(min_time)
這個代碼先計算每個面包機單獨制作兩種面包的時間之和,并找到其中的最小值。然后分別找到制作 a 面包和制作 b 面包最快的面包機,計算它們對應的雙面包機情況的時間,并更新最小時間。最后輸出最小時間。
但這樣可能無法覆蓋所有可能的最優解,比如可能存在某個面包機的 a 時間不是最小,但和另一個面包機的 b 時間組合起來更優的情況。
更好的方法是對所有可能的雙面包機組合進行考慮:
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))min_time = float('inf')# 單面包機情況
for i in range(n):min_time = min(min_time, a[i] + b[i])# 雙面包機情況
for i in range(n):for j in range(n):if i != j:current_time = max(a[i], b[j])if current_time < min_time:min_time = current_timeprint(min_time)
但這種方法的時間復雜度是 O(n2),當 n 較大時(如 100000)會導致超時。
所以需要更高效的方法:
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))min_time = float('inf')# 單面包機情況
for i in range(n):min_time = min(min_time, a[i] + b[i])# 雙面包機情況
min_a = min(a)
min_b = min(b)min_time = min(min_time, max(min_a, min_b))print(min_time)
這種方法只考慮制作 a 最快的面包機和制作 b 最快的面包機的組合,但這也可能錯過一些更優的組合。
更合理的策略是:找到制作 a 面包的 k 臺最快面包機和制作 b 面包的 k 臺最快面包機,然后在這些有限的組合中尋找最優解。這里 k 可以設為 100 或其他較小的值。
n = int(input())
a = list(map(int, input().split()))
b = list(map(int, input().split()))min_time = float('inf')# 單面包機情況
for i in range(n):min_time = min(min_time, a[i] + b[i])# 雙面包機情況
k = 100
sorted_a = sorted(range(n), key=lambda x: a[x])
sorted_b = sorted(range(n), key=lambda x: b[x])for i in range(min(k, n)):for j in range(min(k, n)):if sorted_a[i] != sorted_b[j]:current_time = max(a[sorted_a[i]], b[sorted_b[j]])if current_time < min_time:min_time = current_timeprint(min_time)
這種方法綜合了單面包機和雙面包機的情況,并在有限的組合中尋找最優解,平衡了效率和準確性。時間復雜度主要取決于排序操作和有限次的組合檢查。