leetcode 2483. Minimum Penalty for a Shop

Insert image description here
Insert image description here

The string customers only contains two letters, 'Y' and 'N', indicating whether there are customers in the store at time i.
If the store is open at time i, the cost of 'Y' is 0 and the cost of 'N' is 1. (It is a loss if it is open but there are no customers).
On the contrary, if the door is closed at time i, the cost of 'N' is 0 and the cost of 'Y' is 1. (It is also a loss if the door is closed but a guest comes).

If the store is closed at time j, then it is closed from time j to the end.
Ask at which moment the cost of closing is the least expensive.

Idea:

Method one :

First calculate the cost of always closing the door (closing the door at time 0).
Then move the closing time to the right. At this time, you only need to change the value of the previous moment based on the cost of the previous step.

For example, look at Example1.
First calculate the cost of closing the door at time 0 as 3.

Then the closing time moves to time 1. At this time, it is still in the closed state after time 1, and there is no change in cost. What changes is that the closed state at time 0 becomes the open state.
At this time, the cost at time 0 needs to be modified. Time 0 is 'Y', the cost is 1 when closing the door, and the cost when opening the door is 0. The cost 1 needs to be subtracted from closing the door to opening the door. At this time, subtract more from the cost 3 in the previous step
. The cost of coming out is 1. So the cost of time 1 is 3-1=2.
And so on.
Until it moves to the rightmost side of the string (outside the boundary, which means the door is always open).

During this process, the minimum cost and corresponding moment are recorded.

    public int bestClosingTime(String customers) {
    
    
        char[] chs = customers.toCharArray();
        int cntY = 0;
        int cntN = 0;
        int n = chs.length;
        int[] penalty = new int[n+1];
        int minP = 0;
        int minIdx = 0;

        //从0时刻起不开门的代价
        for(int i = n-1; i >= 0; i--) {
    
    
            if(chs[i] == 'Y'){
    
    
                cntY ++;
                penalty[i] = penalty[i+1] + 1;
            } else {
    
    
                cntN ++;
                penalty[i] = penalty[i+1];
            }
        }
        if(cntY == n) return n;
        if(cntN == n) return 0;

        //i时刻关门
        minP = penalty[0];
        for(int i = 1; i <= n; i++) {
    
    
            if(chs[i-1] == 'Y') penalty[i] = penalty[i-1]-1;
            else penalty[i] = penalty[i-1]+1;
            if(penalty[i] < minP) {
    
    
                minP = penalty[i];
                minIdx = i;
            }
        }
        return minIdx;
    }

Method two :

In fact, there is no need to calculate the cost of closing the door at the initial time 0.
Because what it is does not affect the result.

Still Example1. Let’s rank the costs from 0 to closing the door at the last moment:

3, 2, 1, 2, 1

The price is the smallest at the second time, so choose to close the door at the second time.

At this time, change the cost of closing the door at the initial moment from 3 to 0. Then it is the same as method 1, changing the cost at the previous moment, so we get

0, -1, -2, -1, -2

The result is that the second moment is the least costly. Therefore, it doesn’t matter what the initial cost of closing the door at time 0 is, as long as the time with the smallest cost can be obtained later.

It is omitted to calculate the cost of closing the door at time 0 in method 1. The default cost of closing the door at time 0 is 0.
Then move the door closing time i to the right, and change the cost of the previous moment with each step. For example, moving to time 1 changes the cost of time 0.
Time 0 is 'Y', the cost of closing the door is 1, and the cost of opening the door is 0. Now that the door is opened, the cost is -1, otherwise if it is 'N', the cost is +1.

During the right shift, the minimum cost and corresponding moment are recorded.

    public int bestClosingTime(String customers) {
    
    
        char[] a = customers.toCharArray();
        int n = a.length;
        int j = -1, penalty = 0, minP = 0;
        for (int i = 0; i < a.length; i++) {
    
    
            penalty += a[i] == 'Y'? -1 : 1;
            if (penalty < minP) {
    
    
                j = i;
                minP = penalty;
            }
        }
        return j + 1;
    }

Guess you like

Origin blog.csdn.net/level_code/article/details/132574939