# **APCS Nov 2021 - g597 [Q3](https://zerojudge.tw/ShowProblem?problemid=g597) [Python]** > 本題敘述: > 有 `n` 台機器排成一直線, 每一個機器都有一個數值`t[i]`, 代表該台機器要產出一單位的資料需要`t[i]`單位的時間,接下來有 `m` 個工作要完成, 每一個工作都需要位置在`[l[i],r[i]]`的機器各生產出`w[i]`單位資料,現在你可以調換`n`台機器的順序, 目標是使得這`m`個工作做完的總時間要最小。 > [name=BlackInk7777] 這如果用迴圈慢慢加絕對會超時,所以要使用差分數組來讓這題快一點。 --- # 差分數組解釋: 假設我們有一個初始都為零的數組 dur,大小為 5,如下: ``Array= [0,0,0,0,0]`` 假設要在`[2,5]`內所有元素上加 1、要在`[3,5]`內所有元素上加 2: ### 使用差分數組實現 1. **初始化差分數組 `diff`:** `diff = [0, 0, 0, 0, 0, 0, 0]` 同樣,差分數組的大小是原數組大小加一。 2. **第一個區間 \([2, 4]\) 的加值:** - 在位置 2 上加 1:`diff = [0, 0, 1, 0, 0, 0, 0]` - 在位置 5 上減 1(位置 4 的下一個位置):`diff = [0, 0, 1, 0, 0, -1, 0]` 3. **第二個區間 \([3, 5]\) 的加值:** - 在位置 3 上加 2:`diff = [0, 0, 1, 2, 0, -1, 0]` - 在位置 6 上減 2(位置 5 的下一個位置):`diff = [0, 0, 1, 2, 0, -1, -2]` 4. **通過差分數組統計最終的 `dur` 數組:** - 迴圈 `diff` 並更新 `dur`: - \( i = 1 \):`dur[1] = 0`。 - \( i = 2 \):`dur[2] = 1`(累加得 1)。 - \( i = 3 \):`dur[3] = 3`(累加得 1 + 2)。 - \( i = 4 \):`dur[4] = 3`(累加得 3 + 0)。 - \( i = 5 \):`dur[5] = 2`(累加得 3 - 1)。 - \( i = 6 \):`dur[6] = 0`(累加得 2 - 2)。 ### 結果 最終,`dur` 數組更新為:`dur = [0, 0, 1, 3, 3, 2]` --- # 代碼實作 ```python= def main(): n,m = map(int,input().split()) dur = [0] * (n + 2) diff = [0] * (n + 2) for _ in range(m): l,r,w = map(int, input().split()) diff[l] += w diff[r+1] -= w machine = [int(num) for num in input().split()] currect = 0 for i in range(1 ,len(diff)): dur[i] = currect + diff[i] currect = dur[i] dur.pop(0) dur.pop() times = 0 machine.sort(reverse=True) dur.sort() for i in range(len(dur)): times += dur[i] * machine[i] print(times) if __name__ == "__main__": main() ``` **本題知識** * **差分數組** * **pop**用法:`[(這是陣列)].pop(位置)` **Ex:** ``` the_list = [0,1,2,3,4] the_list.pop(0) // output: [1,2,3,4] ```