解法一:贪心

我自己只能想到贪心的做法了。
先根据满意程度的正负将菜分成两堆(0跟正数分在一起)。实际做菜的时候负数的菜先做,正数的菜后做。
正数堆的菜肯定是全部要做的,而且要按照满意程序升序来做,这样满意程度高的菜乘上的时间系数更大,总的结果也就更大。
负数堆的菜按照降序排列,有选择地做,每做一道菜便意味了后续的所有菜时间系数+1,所以要根据做这道菜带来的负收益和正收益之和是否大于0来决定是否做。

  1. import java.util.Collections;
  2. import java.util.Comparator;
  3. import java.util.LinkedList;
  4. import java.util.List;
  5. class Solution {
  6. public int maxSatisfaction(int[] satisfaction) {
  7. // 正数堆, 包括0
  8. List<Integer> positive = new LinkedList<>();
  9. // 负数堆
  10. List<Integer> negative = new LinkedList<>();
  11. for (int i : satisfaction) {
  12. if (i >= 0) {
  13. positive.add(i);
  14. } else {
  15. negative.add(i);
  16. }
  17. }
  18. // 对正数升序排列
  19. Collections.sort(positive);
  20. // 对负数降序排列
  21. Collections.sort(negative, new Comparator<Integer>() {
  22. @Override
  23. public int compare(Integer o1, Integer o2) {
  24. return o2 - o1;
  25. }
  26. });
  27. // 时间系数
  28. int time = 0;
  29. // 总满意度
  30. int ans = 0;
  31. // 正收益
  32. int sum = 0;
  33. for (Integer i : positive) {
  34. ans += (++time) * i;
  35. sum += i;
  36. }
  37. // 负收益
  38. int sum_ = 0;
  39. for (Integer i : negative) {
  40. sum_ += i;
  41. if (sum + sum_ < 0) {
  42. break;
  43. }
  44. ans += sum + sum_;
  45. }
  46. return ans;
  47. }
  48. }

解法二:贪心

总体思路同解法一,写复杂了😅。
不判断小于0的话也可以写成DP的形式。

  1. import java.util.Arrays;
  2. class Solution {
  3. public int maxSatisfaction(int[] satisfaction) {
  4. Arrays.sort(satisfaction);
  5. int ans = 0;
  6. for (int i = satisfaction.length - 1, sum = 0; i >= 0; --i) {
  7. sum += satisfaction[i];
  8. if (sum < 0) {
  9. break;
  10. }
  11. ans += sum;
  12. }
  13. return ans;
  14. }
  15. }