请帮助我给我一些解决方法。我的想法是贪婪的方法。
问题是:
您在俄罗斯萨马拉(Samara)工作几天,每天都有每单位工作的新工资和每单位食物的新费用。工作1单位需要1单位能量,而吃1单位食物则要增加1单位能量。这里 以下是您的工作要求:
+您到达时一无所有,但精力充沛。您永远不会拥有比到达的能量更多的能量,而且它永远不会是负面的。
+您每天可以做任何数量的工作(可能根本不做任何工作),仅受您的精力限制。当能量为零时,您将无法工作。
+您每天可以吃任何数量的食物(可能根本没有任何食物),受您拥有的钱的限制。当您的钱为零时,您将无法吃饭。
+您可以在一天结束时吃东西,并且吃完饭后不能恢复工作。您可以在第二天恢复工作。 您的真实目标是带回尽可能多的钱。计算您可以带回家的最大金额。
例如,考虑一个3天的住宿,其中每天每单位工作的工资如下:收入= [1、2、4]。食物的成本是成本= [1、3、6]。您从e = 5能量单位开始。
*第一天:1个单位的工作价值1,1个单位的食品成本1.今天没有上班的经济诱因。
*第二天:每工作1单位可赚2,而每工作1单位的食品成本3,因此您吃的东西比总收入要多,因此这一天没有上班的经济诱因。
*第三天:您每工作一个单元可获得4个单元。今天的食物成本是无关紧要的,因为您要直接下班回家。您将所有精力都花在工作上,收取报酬:5 x 4 = 20单位 钱,不用买晚餐就回家。
功能说明 在下面的编辑器中完成函数calculateProfit。该函数必须返回一个整数,该整数表示在住宿结束后可以带回家的最大收入。
到目前为止,我的解决方案(需要改进):
function calculateProfit(n, earning, cost, e) {
// Write your code here
let sum = 0
let ef = e;
let count = 0;
let max = 0;
for (let i = 0; i < n; i++){
if (i != n - 1) {
console.log("next day " + ef + " " + ef * earning[i + 1] + "--" + ef * cost[i]);
if (earning[i] > cost[i]) {
sum += ef * earning[i];
e = 0;
max = 0;
if (ef * earning[i + 1] > ef * cost[i] && sum > 0) {
//console.log(e);
sum -= ef * cost[i];
e = ef;
}
}
else {
count++;
max = Math.max(max, earning[i]);
}
}
else {//last day
if (earning[i] <= cost[i]) {
count++;
}
max = Math.max(max, earning[i]);
if (e > 0)
sum += ef * max;
}
console.log(i, "-", sum," max=",max);
}
console.log("count",count);
if (count == n) {
earning.sort();
sum = earning[n-1] * ef;
}
return sum;
}
答案 0 :(得分:0)
不幸的是,不同的日子不能分开考虑。考虑一个例子,其中劳动和食品在第一天都很昂贵,而第二天又便宜。显然,您将在第一天工作,然后在第二天进餐。
那么,我们该如何解决呢?具有动态程序。在每一天中,您必须做出两个选择:您工作多少,吃多少?一天结束时,您将获得一些总收入和一定的精力。该能量值只能在0和最大能量之间具有几个不同的值。
让我们将两个决策分开,并跟踪每个剩余能量水平的最大收益。假设E_afterWork(day: i, energy: e)
是您在工作第i
天和剩余能量e
后可获得的最高收入。同样,E_afterEat(day: i, energy: e)
是在i
一天进餐后的最大收入。我们将持续跟踪这些值。最后,我们对E_afterWork(day: totalDays - 1, energy: 0)
感兴趣。这就是我们剩下的钱。
第一天,我们可以立即将E_afterWork
设置为:
E_afterWork(day: 0, energy: e) = earning[0] * (maxEnergy - e)
我们在所有能级上都这样做。
然后,我们必须逐渐更新E_afterEat
和E_afterWork
。这些是:
E_afterEat(day: i, energy: e) = maximum over possible previous energy pe (E_afterWork(day: i, energy: pe) - cost[i] * (e - pe))
我们必须检查所有小于或等于pe
的{{1}}值,以及在哪里可以买得起的食物,即结果是否定的。后者应该自动完成,而无需做任何特别的事情。
我们在这里做什么?我们检查当天(下班后)所有可能的结局,并尝试吃不同量的食物。我们保留了使我们获得最大收益的选择(通过将收益计算为完成工作后的收益减去食品成本)。
现在,如何更新e
?这实际上很简单:
E_afterWork
这里的想法相同。
让我们举个例子:
E_afterWork(day: i, energy: e) = maximum over possible previous energy pe (E_afterEat(day: i-1, energy: pe) + earning[i] * (pe - e))
让我们初始化。我将用earning=[7, 2, 4]
cost=[7, 3, 6]
maxEnergy=5
缩写E_afterWork
,用AW
缩写E_afterEat
:
AE
现在更新e | AW(0, e)
--+----------
5 | 0
4 | 7
3 | 14
2 | 21
1 | 28
0 | 35
。对于第一个条目,我们将计算:
AE
下一个工作日:
AE(0, 5) = min (0 - 0 * 7, 7 - 1 * 7, 14 - 2 * 7, 21 - 3 * 7, …) = 0
e | AW(0, e) AE(0, e)
--+--------------------
5 | 0 0
4 | 7 7
3 | 14 14
2 | 21 21
1 | 28 28
0 | 35 35
吃:
e | AW(0, e) AE(0, e) AW(1, e)
--+-----------------------------
5 | 0 0 0
4 | 7 7 7 = max(0 + 1 * 2, 7 + 0 * 2)
3 | 14 14 14 = max(0 + 2 * 2, 7 + 1 * 2, 14 + 0 * 2)
2 | 21 21 21
1 | 28 28 28
0 | 35 35 35
工作:
e | AW(0, e) AE(0, e) AW(1, e) AE(1, e)
--+---------------------------------------
5 | 0 0 0 20
4 | 7 7 7 23
3 | 14 14 14 26
2 | 21 21 21 29 = max(21 - 0 * 3, 28 - 1 * 3, 35 - 2 * 3)
1 | 28 28 28 32 = max(28 - 0 * 3, 35 - 1 * 3)
0 | 35 35 35 35
因此,在第一天工作,第二天进餐以及最后一天工作,您总共可以获得 40 。