Bottom up bitmask DP
Let dp[state][sessionTimeLeft] equals to the number of session we need, example: dp[1101][10] (binary 1101) means the number of sessions we need when selecting 
Let `dp[state][sessionTimeLeft]` equals to the number of session we need, example: `dp[1101][10]` (binary `1101`) means the number of sessions we need when selecting first, second and the third item, and there are 10 seconds left.\n\nNow, if `time >= tasks[i]`, `dp[state][time - tasks[i]] = dp[prevState][time]`.\nOtherwise, we need to start a new session, so `dp[state][sessionTime - tasks[i]] = min(dp[prevState][for t = 0 to sessionTime])`, (we choose the minimum amount of sessions required to transform from prevState to the current state)\n\n```cpp\nclass Solution {\npublic:\n    int minSessions(vector<int>& tasks, int sessionTime) {\n        const int N = tasks.size();\n        vector<vector<int>> dp(1 << N, vector<int>(sessionTime + 1, INT_MAX / 2));\n        dp[0][sessionTime] = 1;\n        for (int state = 0; state < (1 << N); state++) {\n            for (int t = 1; t <= sessionTime; t++) {\n                for (int i = 0; i < tasks.size(); i++) {\n                    if (((state >> i) & 1) == 0) continue;\n                    const int prevState = state - (1 << i);\n                    if (t >= tasks[i]) {\n                        dp[state][t - tasks[i]] = min(\n                            dp[state][t - tasks[i]], \n                            dp[prevState][t]\n                        );\n                    } else {\n                        dp[state][sessionTime - tasks[i]] = min(\n                            dp[state][sessionTime - tasks[i]], \n                            *min_element(begin(dp[prevState]), end(dp[prevState])) + 1\n                        );\n                    }\n                }\n            }\n        }\n        return *min_element(begin(dp[(1 << N) - 1]), end(dp[(1 << N) - 1]));\n    }\n};\n```\n\nTime complexity: `O(NT 2^N)`, where `N` is `tasks.size()`, `T` is `sessionTime`
['Dynamic Programming', 'C']