你正在经营一座摩天轮,该摩天轮共有 4 个座舱  ,每个座舱 最多可以容纳 4 位游客  。你可以 逆时针 runningCost 。摩天轮每次轮转都恰好转动 1 / 4 周。
给你一个长度为 n 的数组 customers , customers[i] 是在第 i 次轮转(下标从 0i 次。每位游客在登上离地面最近的座舱前都会支付登舱成本 boardingCost
你可以随时停下摩天轮,即便是 在服务所有游客之前  。如果你决定停止运营摩天轮,为了保证所有游客安全着陆, 将免费进行  所有后续轮转 下一次轮转  。
返回最大化利润所需执行的 最小轮转次数  。 如果不存在利润为正的方案,则返回 -1 。
示例 1: 
,摩天轮轮转。当前利润为 8 * 6 - 2 * 4 = 40 。
3. 最后 6 位游客抵达,4 位登舱,13 位等待,摩天轮轮转。当前利润为 12 * 6 - 3 * 4 = 60 。
4. 4 位登舱,9 位等待,摩天轮轮转。当前利润为 * 6 - 4 * 4 = 80 。
5. 4 位登舱,5 位等待,摩天轮轮转。当前利润为 20 * 6 - 5 * 4 = 100 。
6. 4 位登舱,1 位等待,摩天轮轮转。当前利润为 24 * 6 - 6 * 4 = 120 。
7. 1 位登舱,摩天轮轮转。当前利润为 25 * 6 - 7 * 4 = 122 。
轮转 7 次得到最大利润,最大利润为122 。
示例 3: 
**输入:** customers = [3,4,0,5,1], boardingCost = 1, runningCost = 92
**输出:** -1
**解释:**
1. 3 位游客抵达,3 位登舱,0 位等待,摩天轮轮转。当前利润为 3 * 1 - 1 * 92 = -89 。
2. 4 位游客抵达,4 位登舱,0 位等待,摩天轮轮转。当前利润为 is 7 * 1 - 2 * 92 = -177 。
3. 0 位游客抵达,0 位登舱,0 位等待,摩天轮轮转。当前利润为 7 * 1 - 3 * 92 = -269 。
4. 5 位游客抵达,4 位登舱,1 位等待,摩天轮轮转。当前利润为 12 * 1 - 4 * 92 = -356 。
5. 1 位游客抵达,2 位登舱,0 位等待,摩天轮轮转。当前利润为 13 * 1 - 5 * 92 = -447 。
利润永不为正,所以返回 -1 。
提示: 
n == customers.length1 <= n <= 1050 <= customers[i] <= 501 <= boardingCost, runningCost <= 100 
方法一:模拟 假设每位游客需要支付的费用是 boardingCost,一次轮转有 curCustomers 位游客登上座舱,每次轮转的运行成本是 runningCost,则摩天轮当前一次轮转的利润是 boardingCost} \times \textit{curCustomers} - \textit{runningCost,其中 boardingCost 和 runningCost 的值是已知的,curCustomers 的值由正在等摩天轮的游客的数量和座舱可以容纳的游客的数量中的最小值决定,其中座舱可以容纳的游客的数量为 4。
对于长度为 n 的数组 customers,customers}[i] 是在第 i 次轮转之前到达的新游客的数量(i 从 0 开始),因此可以根据到达的新游客的数量和登上摩天轮的游客的数量计算每一次轮转时正在等摩天轮的游客的数量。
轮转摩天轮分成两个阶段。第一阶段是前 n 次轮转,每次轮转之前都可能有新游客到达。如果在第一阶段结束之后还有剩余的游客在等摩天轮,则进入第二阶段,将剩余的游客轮转完毕。
对于第一阶段的每次轮转,需要首先计算该次轮转时正在等摩天轮的游客的数量,然后计算该次轮转的利润以及总利润,同时维护最大利润与最大利润的最小轮转次数。具体而言,第 i 次轮转的流程如下:
使用 customers}[i] 的值更新正在等摩天轮的游客的数量;
计算登上座舱的游客的数量,为正在等摩天轮的游客的数量和座舱可以容纳的游客的数量的最小值;
将登上座舱的游客的数量从正在等摩天轮的游客的数量中减去;
计算该次轮转的利润,并计算到该次轮转的总利润;
如果总利润大于最大利润,则更新最大利润与最大利润的最小轮转次数。
 
第一阶段结束后,如果没有剩余的游客在等摩天轮,则直接返回最大利润的最小轮转次数。如果还有剩余的游客在等摩天轮,只有当剩余的游客带来的利润为正时,才需要考虑第二阶段,可能获得更多的利润。
由于每位游客需要支付的费用是正数,因此当座舱满舱时(即座舱上有 4 位游客,达到最大容纳数量),可以达到一次轮转的最大利润。如果一次轮转的最大利润不为正,则第二阶段的利润一定不为正,因此直接返回第一阶段的最大利润的最小轮转次数。
如果一次轮转的最大利润为正,则每次座舱满舱的轮转的利润都为正,因此计算全部满舱轮转之后的总利润,如果大于最大利润则更新最大利润与最大利润的最小轮转次数。最后可能剩下少于 4 位游客,需要进行最后一次非满舱的轮转,在最后一次轮转之后计算总利润,如果总利润大于最大利润则更新最大利润与最大利润的最小轮转次数。
[sol1-Python3] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class  Solution :    def  minOperationsMaxProfit (self, customers: List [int ], boardingCost: int , runningCost: int  ) -> int :         ans = -1          maxProfit = totalProfit = operations = customersCount = 0          for  c in  customers:             operations += 1              customersCount += c             curCustomers = min (customersCount, 4 )             customersCount -= curCustomers             totalProfit += boardingCost * curCustomers - runningCost             if  totalProfit > maxProfit:                 maxProfit = totalProfit                 ans = operations         if  customersCount == 0 :             return  ans         profitEachTime = boardingCost * 4  - runningCost         if  profitEachTime <= 0 :             return  ans         if  customersCount > 0 :             fullTimes = customersCount // 4              totalProfit += profitEachTime * fullTimes             operations += fullTimes             if  totalProfit > maxProfit:                 maxProfit = totalProfit                 ans = operations             remainingCustomers = customersCount % 4              remainingProfit = boardingCost * remainingCustomers - runningCost             totalProfit += remainingProfit             if  totalProfit > maxProfit:                 operations += 1                  ans += 1          return  ans 
[sol1-Java] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 class  Solution  {    public  int  minOperationsMaxProfit (int [] customers, int  boardingCost, int  runningCost)  {         int  ans  =  -1 ;         int  maxProfit  =  0 ;         int  totalProfit  =  0 ;         int  operations  =  0 ;         int  customersCount  =  0 ;         int  n  =  customers.length;         for  (int  i  =  0 ; i < n; i++) {             operations++;             customersCount += customers[i];             int  curCustomers  =  Math.min(customersCount, 4 );             customersCount -= curCustomers;             totalProfit += boardingCost * curCustomers - runningCost;             if  (totalProfit > maxProfit) {                 maxProfit = totalProfit;                 ans = operations;             }         }         if  (customersCount == 0 ) {             return  ans;         }         int  profitEachTime  =  boardingCost * 4  - runningCost;         if  (profitEachTime <= 0 ) {             return  ans;         }         if  (customersCount > 0 ) {             int  fullTimes  =  customersCount / 4 ;             totalProfit += profitEachTime * fullTimes;             operations += fullTimes;             if  (totalProfit > maxProfit) {                 maxProfit = totalProfit;                 ans = operations;             }             int  remainingCustomers  =  customersCount % 4 ;             int  remainingProfit  =  boardingCost * remainingCustomers - runningCost;             totalProfit += remainingProfit;             if  (totalProfit > maxProfit) {                 maxProfit = totalProfit;                 operations++;                 ans++;             }         }         return  ans;     } } 
[sol1-C#] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 public  class  Solution  {    public  int  MinOperationsMaxProfit (int [] customers, int  boardingCost, int  runningCost         int  ans = -1 ;         int  maxProfit = 0 ;         int  totalProfit = 0 ;         int  operations = 0 ;         int  customersCount = 0 ;         int  n = customers.Length;         for  (int  i = 0 ; i < n; i++) {             operations++;             customersCount += customers[i];             int  curCustomers = Math.Min(customersCount, 4 );             customersCount -= curCustomers;             totalProfit += boardingCost * curCustomers - runningCost;             if  (totalProfit > maxProfit) {                 maxProfit = totalProfit;                 ans = operations;             }         }         if  (customersCount == 0 ) {             return  ans;         }         int  profitEachTime = boardingCost * 4  - runningCost;         if  (profitEachTime <= 0 ) {             return  ans;         }         if  (customersCount > 0 ) {             int  fullTimes = customersCount / 4 ;             totalProfit += profitEachTime * fullTimes;             operations += fullTimes;             if  (totalProfit > maxProfit) {                 maxProfit = totalProfit;                 ans = operations;             }             int  remainingCustomers = customersCount % 4 ;             int  remainingProfit = boardingCost * remainingCustomers - runningCost;             totalProfit += remainingProfit;             if  (totalProfit > maxProfit) {                 maxProfit = totalProfit;                 operations++;                 ans++;             }         }         return  ans;     } } 
[sol1-C] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #define  MIN(a, b) ((a) < (b) ? (a) : (b)) int  minOperationsMaxProfit (int * customers, int  customersSize, int  boardingCost, int  runningCost)  {    int  ans = -1 ;     int  maxProfit = 0 ;     int  totalProfit = 0 ;     int  operations = 0 ;     int  customersCount = 0 ;     int  n = customersSize;     for  (int  i = 0 ; i < n; i++) {         operations++;         customersCount += customers[i];         int  curCustomers = MIN(customersCount, 4 );         customersCount -= curCustomers;         totalProfit += boardingCost * curCustomers - runningCost;         if  (totalProfit > maxProfit) {             maxProfit = totalProfit;             ans = operations;         }     }     if  (customersCount == 0 ) {         return  ans;     }     int  profitEachTime = boardingCost * 4  - runningCost;     if  (profitEachTime <= 0 ) {         return  ans;     }     if  (customersCount > 0 ) {         int  fullTimes = customersCount / 4 ;         totalProfit += profitEachTime * fullTimes;         operations += fullTimes;         if  (totalProfit > maxProfit) {             maxProfit = totalProfit;             ans = operations;         }         int  remainingCustomers = customersCount % 4 ;         int  remainingProfit = boardingCost * remainingCustomers - runningCost;         totalProfit += remainingProfit;         if  (totalProfit > maxProfit) {             maxProfit = totalProfit;             operations++;             ans++;         }     }     return  ans; } 
[sol1-C++] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 class  Solution  {public :    int  minOperationsMaxProfit (vector<int >& customers, int  boardingCost, int  runningCost)           int  ans = -1 ;         int  maxProfit = 0 ;         int  totalProfit = 0 ;         int  operations = 0 ;         int  customersCount = 0 ;         int  n = customers.size ();         for  (int  i = 0 ; i < n; i++) {             operations++;             customersCount += customers[i];             int  curCustomers = min (customersCount, 4 );             customersCount -= curCustomers;             totalProfit += boardingCost * curCustomers - runningCost;             if  (totalProfit > maxProfit) {                 maxProfit = totalProfit;                 ans = operations;             }         }         if  (customersCount == 0 ) {             return  ans;         }         int  profitEachTime = boardingCost * 4  - runningCost;         if  (profitEachTime <= 0 ) {             return  ans;         }         if  (customersCount > 0 ) {             int  fullTimes = customersCount / 4 ;             totalProfit += profitEachTime * fullTimes;             operations += fullTimes;             if  (totalProfit > maxProfit) {                 maxProfit = totalProfit;                 ans = operations;             }             int  remainingCustomers = customersCount % 4 ;             int  remainingProfit = boardingCost * remainingCustomers - runningCost;             totalProfit += remainingProfit;             if  (totalProfit > maxProfit) {                 maxProfit = totalProfit;                 operations++;                 ans++;             }         }         return  ans;     } }; 
[sol1-JavaScript] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 var  minOperationsMaxProfit = function (customers, boardingCost, runningCost ) {    let  ans = -1 ;     let  maxProfit = 0 ;     let  totalProfit = 0 ;     let  operations = 0 ;     let  customersCount = 0 ;     const  n = customers.length ;     for  (let  i = 0 ; i < n; i++) {         operations++;         customersCount += customers[i];         let  curCustomers = Math .min (customersCount, 4 );         customersCount -= curCustomers;         totalProfit += boardingCost * curCustomers - runningCost;         if  (totalProfit > maxProfit) {             maxProfit = totalProfit;             ans = operations;         }     }     if  (customersCount === 0 ) {         return  ans;     }     const  profitEachTime = boardingCost * 4  - runningCost;     if  (profitEachTime <= 0 ) {         return  ans;     }     if  (customersCount > 0 ) {         const  fullTimes = Math .floor (customersCount / 4 );         totalProfit += profitEachTime * fullTimes;         operations += fullTimes;         if  (totalProfit > maxProfit) {             maxProfit = totalProfit;             ans = operations;         }         const  remainingCustomers = customersCount % 4 ;         const  remainingProfit = boardingCost * remainingCustomers - runningCost;         totalProfit += remainingProfit;         if  (totalProfit > maxProfit) {             maxProfit = totalProfit;             operations++;             ans++;         }     }     return  ans; }; 
[sol1-Golang] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 func  minOperationsMaxProfit (customers []int , boardingCost, runningCost int ) int  {    ans := -1      var  maxProfit, totalProfit, operations, customersCount int      for  _, c := range  customers {         operations++         customersCount += c         curCustomers := min(customersCount, 4 )         customersCount -= curCustomers         totalProfit += boardingCost*curCustomers - runningCost         if  totalProfit > maxProfit {             maxProfit = totalProfit             ans = operations         }     }     if  customersCount == 0  {         return  ans     }     profitEachTime := boardingCost*4  - runningCost     if  profitEachTime <= 0  {         return  ans     }     if  customersCount > 0  {         fullTimes := customersCount / 4          totalProfit += profitEachTime * fullTimes         operations += fullTimes         if  totalProfit > maxProfit {             maxProfit = totalProfit             ans = operations         }         remainingCustomers := customersCount % 4          remainingProfit := boardingCost*remainingCustomers - runningCost         totalProfit += remainingProfit         if  totalProfit > maxProfit {             maxProfit = totalProfit             operations++             ans++         }     }     return  ans } func  min (a, b int ) int  {    if  a > b {         return  b     }     return  a } 
复杂度分析