当前位置:网站首页>Cartoon: interesting "cake cutting" problem

Cartoon: interesting "cake cutting" problem

2022-06-11 14:22:00 Big data V

e9b5957772e7859dcb4c56fc6c57a694.gif

Reading guide : It's brain burning and interesting ACM The title of the competition .

author : Ash

source : Programmer Xiaohui (ID:chengxuyuanxiaohui)

62ffdf7f38f3f32491db4cb7ea79f3d7.png

18f10eba6bf7cbc0c88900488a6e449e.png

—————  the second day   —————

a6146e89fdbfe4c9378a4cc28aab6614.png

18ce2dc89e90908820d2573bb6681b4d.png

add9abd286c1573a187d7b939e597ac5.png

for instance :

We have 5 A piece of cake , What's the size of the cake  5,17,25,3,15 

640fde67e07dc4d49eae5362ca59db28.png

We have 7 Customers , Their appetite is  2,5,7,9,12,14,20

ec5ef0c2921efa5c97c401de2fdf0702.png

( The size of each cake and the amount of food the customer eats are less than 1000 The integer of , The number of cakes and customers does not exceed 1000)

In the distribution of the cake , There is a special rule : Cake can be divided or not .

What does that mean ?

A bigger cake , It can be cut into small pieces , To satisfy multiple customers with less appetite :

eaa34aa2d17f52fa6af79518561bd48f.png

however , Some smaller cakes , Don't allow Merge into a big cake , To satisfy a customer with a big appetite :

96165dd7ac8fcc43aba0b949d0b60e94.png

The last question is : A set of given cake sizes cakes, A set of meals for a given customer mouths, How to calculate the maximum number of customers these cakes can satisfy ?

  • such as : Input cakes aggregate {2,9}; Input mouths aggregate {5,4, 2,8}

  • Correct return :3

de6e54101c49c3226fdc7439015cd53f.png

383c196c805899ecaf57b7de99126250.png

48d85dd89ffacfa7045b90af75518d29.png

2b90c5de83fab1ceb0e3d22ec91dc092.png

Xiao Hui's idea :

In order to satisfy more customers , Be sure to give priority to customers with a small amount of food , So Xiaohui decided to use Greedy Algorithm .

First , Sort the cake and customers from small to large :

Follow the example above , The results are as follows :

2e80003a5db2face5c8c6ab51cd82a31.png

Next , Let each cake match the customer from left to right . If the cake is bigger than the customer's appetite , Cut the cake ; If the cake is less than the customer's appetite , Then discard the cake .

The first 1 The size of the cake is 3, The first 1 A customer's appetite is 2, So I cut the cake into 2+1, Satisfy customers . The rest 1 Big and small cakes can't satisfy the next customer , discarded .

a6a008a31acb27517c297372955bc537.png

The first 2 The size of the cake is 5, The first 2 A customer's appetite is 5, Just to satisfy the customers .

4ba50fe03bd105f62450a104eedb1f04.png

The first 3 The size of the cake is 15, The first 3 A customer's appetite is 7, So I cut the cake into 7+8, Satisfy customers . The rest 8 Big and small cakes can't satisfy the next customer , discarded .

04f98fd8f5308dc1b25bb691f80aced6.png

The first 4 The size of the cake is 17, The first 4 A customer's appetite is 9, So I cut the cake into 9+8, Satisfy customers . The rest 8 Big and small cakes can't satisfy the next customer , discarded .

7a589bc1b5f3e2e0842ee466b49ddade.png

The first 5 The size of the cake is 25, The first 5 A customer's appetite is 12, So I cut the cake into 12+13, Satisfy customers . The rest 13 Big and small cakes can't satisfy the next customer , discarded .

96165e87a834aa9b117601b7e09e07b6.png

thus , All the cakes are used up , From the greedy algorithm , The maximum number of customers that can be satisfied is 5.

6407b3eed01ff6c6899fa2d6e7fec3b1.png

bc2abb545dae0d5b2f534f6b0f5014e5.png

In the example :

  • 3 My cake is full of 2 Customers ,

  • 5 My cake is full of 5 Customers ,

  • 15 My cake is full of 12 Customers ,

  • 17 My cake is full of 7 and 9 Customers ,

  • 25 My cake is full of 14 Customers .

obviously , How to eat as the interviewer likes , To satisfy the 6 A customer .

384f500f04ce15e6b7d4a081f2c0b6eb.png

23e27d6e5c084e43538dfca175c4357e.png

————————————

0869f78c1694e5a574b742197c3ed7c2.png

a6dd61428d83d49634498ef37b9e060b.png

f382b3e1624c8c9bf7e25b8233c6bb43.png

e024ad67687333265bb416d2ce5ee44b.png

26a3847d05ba3b03b8fbdd0f05b92ac3.png

9ca912449ca9ddf254958d332382c389.png

This sentence sounds a bit circuitous , What does that mean ? Let's take a look at the picture below :

5336e17268c06c13452266ca99d80813.png

In fact, it's very simple , Because customers' appetite is ranked from small to large , Give priority to small customers , To satisfy as many people as possible .

therefore , In the array that records how much customers eat , There must be a continuous element from the far left , In line with the current cake can meet the most customer portfolio .

thus , Our topic starts with Looking for the maximum number of satisfied customers , Transformed into Find the maximum satisfaction critical point in the ordered array of customers' appetite :

639215dedec2f9c97121bb30851997a5.png

4a48cb748890870dd1a4310ba11c3913.png

4cd08e7725289a6d69eb944c63225785.png

Let's review the idea of binary search :

c2de462a25627462b5e6c78cdb92abd2.png

1. Choose the middle element , Subscript mid = (0 + 6)/2 = 3  , So the intermediate element is 9:

0a58afaf3e3710853970e51e6150007f.png

2. Judge 9>5, Select element 9 The middle element on the left side , Subscript mid = (0+2)/2 = 1, So the intermediate element is 5:

ab14c233db7a59ec4dfc0e1f89fc757d.png

3. Judge 5=5, Find the end .

however , The problem of cake cutting is much more complicated than the ordinary binary search , Because we're looking for the critical element of the customer appetite array , It's not a simple matter of judging whether the elements are equal , It's about verifying that a given cake meets all the customers before the critical element .

How do you do that ? We're still using the example , Show me the details :

b67d286b09dda207a28a1d69940719e1.png

First step , Look for the middle element of the customer array .

ad locum , The middle element is 9:

c6fdef251aea3d492e9767f7f6cb1599.png

The second step , Verify the appetite from 2 To 9 Whether our customers can satisfy .

substep 1, Traversing the cake array , Look for bigger than 9 The cake , Finally, we find the elements 15.

25bd2d2309728ad31613a76200c8620e.png

substep 2, Appetite 9 Our customers eat 15 The cake , And then there were 6 size .

9bf30ea53fb2debffc847c1a5ce20e84.png

substep 3, Traverse the cake array again , Look for bigger than 7 The cake , Finally, we find the elements 17.

c71acc7d02920f03754a2776c8c2c9d6.png

substep 4, Appetite 7 Our customers eat 17 The cake , And then there were 10 size .

fedc77e0163e681d0be288db7064d069.png

substep 5, Traverse the cake array again , Look for bigger than 5 The cake , Finally, we find the elements 5.

3ead8eeed70b31532190600880ebc00f.png

substep 6, Appetite 5 Our customers eat 5 The cake , And then there were 0 size .

74089074a6ee726c29e7b3e9e592196f.png

substep 7, Traverse the cake array again , Look for bigger than 2 The cake , Finally, we find the elements 3.

b8a2dc4ad29d4f3f070b0efc88da952a.png

substep 8, Appetite 2 Our customers eat 3 The cake , And then there were 1 size .

f96ac5a7766a93230b57dad30fbc76e4.png

Only this and nothing more , from 2 To 9 All of our customers are satisfied , Verify success .

Next , We need to bring in more customers , So as to try to find out the upper limit of customers that the cake can satisfy .

The third step , Rediscover the middle element of customer array .

Because the second step is successful , So we're going to be in the element 9 The area on the right , Looking for the middle element again . obviously , This intermediate element is 14:

ba6223765625db0e572e4916609af388.png

Step four , Verify the appetite from 2 To 14 Whether our customers can satisfy .

The idea of this step is the same as that of the second step , I won't go into details here . The final verification result is , from 2 To 14 Our customers can satisfy .

Next , We need to bring in more customers , Try to find out the upper limit of customers that cake can satisfy .

Step five , Rediscover the middle element of customer array .

Because the fourth step is successful , So we're going to be in the element 14 The area on the right , Looking for the middle element again . obviously , This intermediate element is the only element 20:

96bec4496b9c9cf56b65474a56a22991.png

Step six , Verify the appetite from 2 To 20 Whether our customers can satisfy .

This step and the second step 、 The fourth step is the same , I won't go into details here . The final verification result is , from 2 To 20 Customers Can't Satisfy .

Go through the above steps , We found the critical point to satisfy our customers 14, from 2 To 14 share 6 A customer , therefore The maximum number of customers a given cake can satisfy is 6.

49240a289ed05ed59ce67d2e1f9c1e3f.png

e0e6a8c3d283f565eda27a823ad2f6cb.png

// Number of cakes left 
static int leftCakes[];
// The total amount of cake ( Not quantity , It's the sum of size )
static int totalCake = 0;
// Waste cake quantity 
static int lostCake = 0;
static boolean canFeed(int[] mouths, int monthIndex, int sum)
{
   if(monthIndex<=0) {
       // Recursive boundary 
       return true;
   }
   // If   The total amount of cake - Waste cake quantity   Less than the current demand , Go straight back to false, That is, it can't meet 
   if(totalCake - lostCake < sum) {
       return false;
   }
   // Traverse the cake from small to large 
   for(int i=0;i<leftCakes.length; i++) {
       if (leftCakes[i] >= mouths[monthIndex]) {
           // Find and eat the matching cake 
           leftCakes[i] -= mouths[monthIndex];
           // The remaining cake is less than the minimum demand , Become a waste of cake 
           if (leftCakes[i] < mouths[1]){
               lostCake += leftCakes[i];
           }
           // Continue to recursive , Try to satisfy mid Requirements before subscribing 
           if (canFeed(mouths, monthIndex-1, sum)) {
               return true;
           }
           // Unable to meet demand , Cake state rollback 
           if (leftCakes[i] < mouths[1]) {
               lostCake -= leftCakes[i];
           }
           leftCakes[i] += mouths[monthIndex];
       }
   }
   return false;
}
public static int findMaxFeed(int[] cakes, int[] mouths){
   // The cakes are arranged in ascending order , And put 0 The subscript is empty 
   int[] cakesTemp = Arrays.copyOf(cakes, cakes.length+1);
   Arrays.sort(cakesTemp);
   for(int cake: cakesTemp){
       totalCake += cake;
   }
   // Customers' appetites are in ascending order , And put 0 The subscript is empty 
   int[] mouthsTemp = Arrays.copyOf(mouths, mouths.length+1);
   Arrays.sort(mouthsTemp);
   leftCakes = new int[cakes.length+1];
   // Sum of demands ( Subscript 0 The element is 0 The sum of individual needs , Subscript 1 The most important element is 1 The sum of individual needs , Subscript 2 The most important element is 1,2 The sum of individual needs .....)
   int[] sum = new int[mouths.length+1];
   for(int i=1;i<=mouths.length;i++) {
       sum[i] = sum[i - 1] + mouthsTemp[i];
   }
   //left and right Used to calculate binary search “ Midpoint ”
   int left=1,right=mouths.length;
   // If the total amount of appetite is greater than the total amount of cake ,right Move the pointer to the left 
   while(sum[right]> totalCake){
       right--;
   }
   // Median pointer , Used for binary search 
   int mid=((left+right)>>1);
   while(left<=right)
   {
       // Reset the remaining cake array 
       leftCakes = Arrays.copyOf(cakesTemp, cakesTemp.length);
       // Reset wasted cake quantity 
       lostCake =0;
       // Recursively find the critical point to meet the requirements 
       if(canFeed(mouthsTemp, mid, sum[mid])){
           left=mid+1;
       } else {
           right = mid - 1;
       }
       mid=((left+right)>>1);
   }
   // Finally, we find the critical point which is just satisfied 
   return mid;
}
public static void main(String[] args) {
   int[] cakes = new int[]{3,5,15,17,25};
   int[] mouths = new int[]{2,5,7,9,12,14,20};
   int maxFeed = findMaxFeed(cakes, mouths);
   System.out.println(" Maximum number of satisfied customers :" + maxFeed);
}

This code is more complicated , A few points need to be explained :

  1. The mainstream method findMaxFeed, Perform various initializations , Control the binary search process .

  2. Method canFeed, It is used to check whether the customers before a certain position can be satisfied by a given cake .

  3. Array leftCakes, Used to temporarily store the remaining cake size , Every time you reset the middle subscript , This array needs to be reset .

c65b93787b52b3d28588b3c9004380e3.png

91900cb737a83400e20c8702fb95ca6f.png

5bed63b5c44d7cc8d8394d2778e06b4e.png

a657b1a4ebb9b39425ffbae0822d74f4.png

add1636d2d02142482bd8c1f24f3b0c1.gif

Extended reading

403c4e612fee573974138f36d2c1ffe6.png

Extended reading 《 Introduction to algorithms 》

Dry goods go straight to

More exciting

Enter the following dialog box in the official account dialog box key word

See more quality content !

read  |  book  |  dried food   Make it clear  |  God operation  |  handy

big data  |  Cloud computing  |  database  | Python |  Reptiles  |  visualization

AI |  Artificial intelligence  |  machine learning  |  Deep learning  | NLP

5G |  Zhongtai  |  User portrait   mathematics  |  Algorithm   Number twin

According to statistics ,99% The big coffee is concerned about the official account

原网站

版权声明
本文为[Big data V]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/162/202206111406489111.html