function dpOptAnyDealCnt(arr, dealCnt) {
if (arr.length <= 0 || dealCnt === 0) {
return 0;
}
let L = dealCnt * 2 - 1;
let buySell2d = Array.from({ length: L }, (v, i) =>
Array(arr.length).fill(0)
);
let opt2d = Array.from({ length: dealCnt }, (v, i) =>
Array(arr.length).fill(0)
);
let prev = buySell2d[0];
let minPos = 0;
for (let i = 1; i < arr.length; i++) {
let vEnd = arr[i];
let min = arr[minPos];
prev[i] = min < vEnd ? prev[i - 1] : i;
minPos = vEnd < min ? i : minPos;
for (let j = 0; j < L; ++j) {
let dealNo = Math.floor(j / 2);
let isSell = j % 2 === 1;
if (isSell) {
let buy = buySell2d[j - 1];
let sell = buySell2d[j];
let a =
Math.max(0, vEnd - arr[buy[i]]) +
(dealNo === 0 || buy[i] === 0 ? 0 : opt2d[dealNo - 1][buy[i] - 1]);
let b = opt2d[dealNo][i - 1];
opt2d[dealNo][i] = Math.max(a, b);
sell[i] = a < b ? sell[i - 1] : i;
} else {
let buy = buySell2d[j];
let a = dealNo === 0 ? 0 : opt2d[dealNo - 1][i - 1];
let b =
Math.max(0, vEnd - arr[buy[i - 1]]) +
(dealNo === 0 || buy[i - 1] === 0
? 0
: opt2d[dealNo - 1][buy[i - 1] - 1]);
opt2d[dealNo][i] = Math.max(a, b);
buy[i] = a < b ? buy[i - 1] : i;
}
}
}
return _.max(opt2d[dealCnt - 1]);
}