公告歡迎來到 Larry's notes,近期會持續整理網站。
※ LeetCode, UVa 與 YZUCSE 系列相關文章已從首頁的文章列表中移除。可從首頁的釘選分類瀏覽。
※ LeetCode, UVa 與 YZUCSE 系列相關文章已從首頁的文章列表中移除。可從首頁的釘選分類瀏覽。
UVa - 10912 解題紀錄
題目: UVa - 10912 - Simple Minded Hashing
題目說明
26 個英文字母,依序從 1 開始編號,a = 1, b = 2, …, z = 26。
給兩個整數 L、S,求使用 L 個英文字母,組成編號總和為 S 的嚴格遞增字串的字串個數。
Input: 每組測資有兩個整數,依序為 L、S。若皆為 0 表結束。
Output: 輸出使用 L 個英文字母,組成編號總和為 S 的嚴格遞增字串的字串個數。
解題思路
動態規劃題,由於測資範圍不大,因此先算出所有情況的答案再輸出即可。
由於組成的字串必須是嚴格遞增,因此最多只會有 26 個字母,且編號總和最大為 351 ( 1 + 2 + … + 26 )。
定義 dp[i][j][k] 表只使用前 i 個字母 ( 編號 1 ~ i 的字母 ),組成長度為 j,總和為 k 的字串的所有情況數,先設定初始狀態 dp[n][1][n] = 1,對於所有 1 <= n <= 26,因為若只有一個字母,組成與自己編號總和相同的字串,必定就是只有自己一種情況而已。
對於 dp[i][j][k]:
- 若
k < i,表示i無法出現在字串中,則dp[i][j][k] = max(dp[i - 1][j][k], dp[i][j][k])。 - 若
k >= i,表示i可以出現在字串中,則dp[i][j][k] += dp[i - 1][j - 1][k - i],可以理解為若要將i放入字串中,可能數為 最大可能字母為i - 1,長度為j - 1,總和為k - i的字串,因為將i接上後會組成 最大可能字母為i,長度為j,總和為k的字串。
簡單來說,就是不斷枚舉是否能將字母放入最後一位,若無法則至少情況數會是 i - 1 的情況數,這樣才符合最初 dp 數組的定義。
參考解法
1 |
|
由於只需要使用 26 個字母的情況,所以可以縮一維。
1 |
|
參考資料
UVa/10912 - Simple Minded Hashing.cpp at master · morris821028/UVa
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 Larry's notes!
評論