class Solution {
 public:
  int minArraySum(vector<int>& nums, int k, int op1, int op2) {
    vector<vector<vector<int>>> mem(
        nums.size(),
        vector<vector<int>>(op1 + 1, vector<int>(op2 + 1, INT_MAX)));
    return minArraySum(nums, 0, op1, op2, k, mem);
  }
 private:
  // Returns the minimum sum of nums[i..n - 1] with `op1` operations of op1 and
  // `op2` operations of op2.
  int minArraySum(const vector<int>& nums, int i, int op1, int op2, int k,
                  vector<vector<vector<int>>>& mem) {
    if (i == nums.size())
      return 0;
    if (mem[i][op1][op2] != INT_MAX)
      return mem[i][op1][op2];
    int res = nums[i] + minArraySum(nums, i + 1, op1, op2, k, mem);
    if (op1 > 0)
      res = min(res, (nums[i] + 1) / 2 +
                         minArraySum(nums, i + 1, op1 - 1, op2, k, mem));
    if (op2 > 0 && nums[i] >= k)
      res = min(res,
                nums[i] - k + minArraySum(nums, i + 1, op1, op2 - 1, k, mem));
    if (op1 > 0 && op2 > 0) {
      if ((nums[i] + 1) / 2 >= k)
        res = min(res, (nums[i] + 1) / 2 - k +
                           minArraySum(nums, i + 1, op1 - 1, op2 - 1, k, mem));
      if (nums[i] >= k)
        res = min(res, (nums[i] - k + 1) / 2 +
                           minArraySum(nums, i + 1, op1 - 1, op2 - 1, k, mem));
    }
    return mem[i][op1][op2] = res;
  }
};