题目
人气一开始是一个偶数,目标也是一个偶数,每次点赞会让人气+2,花费x,送礼物会让人气*2,花费y,点踩会让人气-2,花费z,求最少的花费数量,x、y、z由系统输入
- 和找零钱问题相似的另一种递归方式,该方式递归需要手动设置更多的base case终止条件
- 递归规则,三种方式递归实现遍历每一种选择,但是因为存在 -2 的递归,使得之前递归 f(2)依赖的后序条件可能会和f(2)重复造成无限递归,所以要设置很多终止条件
// 人气+2方式
let p1 = process(
preMoney + add,
aim,
add,
times,
del,
cur + 2,
limitAim,
limitCoin
);
// 人气-2方式
let p2 = process(
preMoney + del,
aim,
add,
times,
del,
cur - 2,
limitAim,
limitCoin
);
// 人气*2方式
let p3 = process(
preMoney + times,
aim,
add,
times,
del,
cur * 2,
limitAim,
limitCoin
);
function main(add, times, del, start, end) {
return process(
0,
end,
add,
times,
del,
start,
end * 2, // 人气边界
((end - start) / 2) * add //平凡解边界
);
function process(preMoney, aim, add, times, del, cur, limitAim, limitCoin) {
// 每次点赞+2,一定能达到的最差解
if (preMoney > limitCoin) {
return Infinity;
}
if (cur < 0) {
return Infinity;
}
// 人气超高2倍手动终止
if (cur > limitAim) {
return Infinity;
}
if (aim === cur) {
return preMoney;
}
let min = Infinity;
// 人气+2方式
let p1 = process(
preMoney + add,
aim,
add,
times,
del,
cur + 2,
limitAim,
limitCoin
);
if (p1 !== Infinity) {
min = p1;
}
// 人气-2方式
let p2 = process(
preMoney + del,
aim,
add,
times,
del,
cur - 2,
limitAim,
limitCoin
);
if (p2 !== Infinity) {
min = Math.min(min, p2);
}
// 人气*2方式
let p3 = process(
preMoney + times,
aim,
add,
times,
del,
cur * 2,
limitAim,
limitCoin
);
if (p3 !== Infinity) {
min = Math.min(min, p3);
}
return min;
}
}