https://leetcode.com/problems/minimum-time-to-break-locks-i/description/

class Solution {
public:
    int findMinimumTime(vector<int>& strength, int k) {
        int n = strength.size();
        vector<int> f(1 << n, INT_MAX);
        f[0] = 0;
        for (int len = 1; len <= n; len++) {
            for (int i = 0; i < (1 << n); i++) {
                int cnt = 0;
                for (int j = 0; j < n; j++)
                    if ((i >> j) & 1) cnt += 1;
                if (cnt != len) continue;
                for (int cur = 0; cur < n; cur++) {
                    if (!((i >> cur) & 1)) continue;
                    int pre = i - (1 << cur);
                    int x = 1 + (k * (len - 1));
                    int need = strength[cur] - x * (len != 1);
                    int time = (need > 0 ? (need / x + ((need % x) != 0)) : 0) + 1;
                    f[i] = min(f[i], f[pre] + time);
                }
            }
        }
        return f[(1 << n) - 1] - 1;
    }
};

這也是一種 DP 的套路題目,我們可以稱他為 bit-dp

如果對於這種 bottom-up 的 DP 沒辦法理解的話,你可以考慮使用 top-down 的方式來解出這題,使用 top-down 就是我們先有一個遞迴的函數,他可以找出所有的排列順序,也就是假設現在有 3 個關卡,我們可以透過遞迴找到 [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1],這 6 種的排列方式。之後再根據這樣的順序找到最小花費的時間作為答案。