有一款被譽為智力考驗的紙牌遊戲,名為「แคง (Kang)」。在這個遊戲中,每張牌都有一個正整數分數。遊戲開始時,你會拿到 $N$ 張牌握在手中,桌面上還正面朝上由左至右排列著另外 $M$ 張牌。你可以看到所有牌的分數,包括你手中拿到的牌以及桌面上擺放的牌。接下來,你可以從桌面上額外摸 $k$ 輪牌,必須按由左至右的順序每次摸一張。在每一輪摸牌之後,你可以執行 1 次棄牌操作:將手中任意數量且分數相同的牌一起丟棄。你需要規劃出牌策略,使得在完成 $k$ 輪從桌面摸牌和從手中棄牌之後,手中剩餘牌的分數總和最小。
考慮以下範例:
假設開始時你手中有五張牌,分數分別為 $6, 3, 9, 6, 3$,而桌面上由左至右擺放的牌分數依次為 $4, 6, 9, 6$。
當 $k = 1$ 時:如果你只能從桌面上摸 1 張牌,當你摸起第一張牌後,你擁有的牌的分數變為 $6, 3, 9, 6, 3, 4$。隨後你可以選擇將分數相同的牌丟棄 1 次。最佳的做法是選擇將 2 張分數為 $6$ 的牌丟棄,從而使剩餘牌的分數總和達到最小值 $3 + 9 + 3 + 4 = 19$。
當 $k = 2$ 時:如果你可以從桌面上摸 2 張牌,最佳策略是:在摸起第一張分數為 $4$ 的牌後,選擇丟棄一張分數為 $9$ 的牌,此時手中剩餘牌的分數為 $6, 3, 6, 3, 4$。接著,當你摸起第 2 張分數為 $6$ 的牌時,你可以丟棄 3 張分數為 $6$ 的牌,使得剩餘牌的分數總和達到最小值 $3 + 3 + 4 = 10$。
當 $k = 3$ 時:如果你可以從桌面上摸 3 張牌,最佳策略是:當你摸起第一張牌後,手中牌的分數變為 $6, 3, 9, 6, 3, 4$。隨後選擇將分數相同的牌丟棄 1 次,最佳的做法是將 2 張分數為 $3$ 的牌全部丟棄,手中剩下 $6, 9, 6, 4$。接著,當你摸起第 2 張分數為 $6$ 的牌時,你可以丟棄 3 張分數為 $6$ 的牌,手中剩下 $9, 4$。而當你第 3 次摸起分數為 $9$ 的牌時,你可以將 2 張分數為 $9$ 的牌全部丟棄,使得剩餘牌的分數總和為 $4$。
當 $k = 4$ 時:如果你可以從桌面上摸 4 張牌,最佳策略是:在摸起第一張分數為 $4$ 的牌後,選擇丟棄一張分數為 $4$ 的牌,手中剩餘牌的分數為 $6, 3, 9, 6, 3$。接著第 2 次摸起的牌分數為 $6$,最佳做法是將 2 張分數為 $3$ 的牌全部丟棄,手中剩下 $6, 9, 6, 6$。第 3 次摸起的牌分數為 $9$,選擇將 2 張分數為 $9$ 的牌全部丟棄。最後摸起最後一張分數為 $6$ 的牌時,你可以丟棄 4 張分數為 $6$ 的牌。這次棄牌後手中不再剩餘任何牌,這意味著牌的分數總和為 $0$。
你的任務(Your Task)
對於 $k = 1, 2, 3, \ldots, M$,求出完成 $k$ 輪之後「手中剩餘牌的最小分數總和」。
本題採用與常規格式不同的程式設計方式,該方式將在正式比賽中使用。關於使用方法,請參閱本題末尾的說明。
實作細節
你需要撰寫以下函式:
std::vector<long long> capsize(std::vector<int> A, std::vector<int> B)
參數說明如下:
- $A$ 是一個長度為 $N$ 的陣列,表示初始時手中各張牌上的數字。
- $B$ 是一個長度為 $M$ 的陣列,按由左至右的順序表示桌面上擺放的各張牌上的數字。
- 該函式需要回傳一個長度為 $M$ 的陣列 $C$,表示當 $k = 1, 2, 3, \ldots, M$ 時,經過 $k$ 輪後手中牌可能達到的最小分數總和。
例如,如果 $A = [6, 3, 9, 6, 3]$ 且 $B = [4, 6, 9, 6]$,函式應當回傳陣列 $[19, 10, 4, 0]$。
資料範圍
- $1 \le N, M \le 10^6$
- 對於每個滿足 $1 \le i \le N$ 的 $i$,均有 $1 \le A[i] \le 10^9$
- 對於每個滿足 $1 \le i \le M$ 的 $i$,均有 $1 \le B[i] \le 10^9$
子任務
| 子任務編號 | 該子任務最高分值 | 條件 |
|---|---|---|
| 1 | 5% | $N, M \le 5$ |
| 2 | 7% | $N \le 1\,000$ 且 $M = 1$ |
| 3 | 8% | $N, M \le 1\,000$,所有牌(包括手中的牌和桌面上展示的牌)上的數字皆相異 |
| 4 | 12% | $N, M \le 1\,000$,所有額外摸到的牌數值全部相同 |
| 5 | 16% | $N, M \le 1\,000$ |
| 6 | 28% | $N, M \le 100\,000$ |
| 7 | 24% | 無額外限制條件 |
說明
程式設計指南
在本題中,撰寫程式並將其提交到評測系統(Grader)的方式與參賽者需要自行撰寫輸入讀取和輸出列印部分的常規格式不同。在本題中,參賽者只需在指定的函式內撰寫必要的計算部分。所有輸入資料均可透過函式的參數取得,計算結果也同樣必須透過函式回傳。參賽者無需撰寫讀取輸入的程式碼,也無需撰寫輸出程式碼。
參賽者將獲得以下若干檔案。參賽者只需按照題目要求修改唯一指定的檔案,並將該檔案提交至系統:
grader.cpp是負責讀取輸入和輸出的主檔案。kang.cpp是參賽者撰寫各項計算程式的檔案,也是參賽者需要提交到系統的檔案(在kang.cpp檔案中禁止包含main()函式,但可以定義其他函式)。run_cpp.sh是參賽者可以呼叫以執行整個程式的檔案。compile_cpp.sh是參賽者可以呼叫以編譯程式的檔案。
參賽者將獲得一個可從系統下載的 .zip 壓縮檔,解壓縮(extract)後包含上述全部 4 個檔案。參賽者應當使用文字編輯器或 IDE 修改 kang.cpp 檔案,並透過呼叫 compile_cpp.sh 或 run_cpp.sh 來編譯或執行程式。
當參賽者呼叫 run_cpp.sh 執行程式時,程式將按照 grader.cpp 檔案中的定義執行,「評測程式檔案說明」一節解釋了該檔案的運作方式。