Algorithm 28: number of exchanges in Bubble Sorting

Source: Internet
Author: User
Problem description

Source: topcoder SRM 627 div2 bubblesortwithreversals

Given the array to be sorted A, after a non-Intersecting sub-array with a maximum of k a is reversed, A is sorted by bubble. What is the minimum number of swap times? The pseudocode for Bubble Sorting is as follows:

Bubblesort ():

Loop Len (a)-1 times:

For I from 0 to Len (a)-2:

If (A [I]> A [I + 1])

Swap (A [I], a [I + 1])

Problem Analysis

First, it is easy to analyze and obtain: For any array to be sorted, the number of swap requests required for Bubble Sorting = the number of reverse pairs in. This is because the Bubble sorting process is used to determine whether the two elements are in reverse order (that is, the small elements are placed behind the large elements) for any two elements. If the two elements are in reverse order, swap. The conclusion above is obvious.

[Idea 1]Next, the problem is to find the minimum value of the reverse logarithm of a given array after the reverse is at most K sub-arrays. Given an array A, it is relatively simple to solve the reverse logarithm. You can directly judge and count two for loops. The problem is hard to allow a reverse Up to K sub-arrays, so we need to consider reverse 0, 1, 2 ,..., k sub-array. If we consider the reverse K (0 = <k <= k) Sub-array, we also need to find the K sub-array, reverse, and then calculate the reverse logarithm, this situation is much more complicated, and it is difficult to clarify the clues. It seems that this road is hard to get through.

[Idea 2]We realized that this is a typical optimization problem. Dynamic Planning for complex optimization problems is an artifact. Let's try it. Dynamic Planning must meet two conditions: (1)Overlapping subproblemsThat is, some smaller subproblems will be solved repeatedly in the process of solving the optimal solution; (2)Optimal sub-structureThat is, the optimal solution of the current problem can be obtained through the optimal solution of its subproblems.

Considering that the number of backward logarithm = subscript I contributed by subscript J satisfies the requirements of I <J & A [I]> A [J], that is, the number of elements before J and in a [J] descending order. It is easy to see that the sorting of elements before subscript J does not affect the inverse logarithm of contribution of subscript J, because no matter how the elements before subscript J are sorted, the number of elements greater than a [J] does not change. Define a subproblem f (x, k) to indicate the inverse logarithm contributed by all subscripts J greater than X after a maximum of K non-overlapping subarrays are reverse, that is, \ [F (x, k) = \ sum _ {J >=x} ^ {n} contribution (J ), with \ revserse \ at \ most \ K \ disjoint \ subarrays \] Then f (0, k) indicates that after a maximum of K reverse subarrays are not overlapped, the reverse logarithm composed of all elements j> = 0 is the solution of the original problem.

[1] Base case: F (n, k) = 0, K = 0, 1,..., K, because there is no subscript greater than or equal to n. There are two scenarios,

[2] The subarray of reverse does not contain X: At this time, the value of f (x, k) is equal to the reverse logarithm with X contribution + Y (Y> = x + 1) the reverse logarithm of contribution. Because the reverse array does not contain X, the subarray before X does not affect the reverse logarithm of X contribution regardless of the reverse, therefore, the reverse subarray can have a maximum of K subarrays after X, and \ [F (x, K) = contribution (x) + f (x + 1, k) \]

[3] The subarray of reverse contains x: now we only need to consider the subarray of reverse from X (why? In other cases, we can convert it to this situation). Suppose we reverse the sub-array (A [X], a [x + 1],... A [Y-1], a [y]) to get the sub array (A [Y], a [Y-1],..., A [x + 1], a [x]), we need to calculate all contribution (J), x <= j <= y. to calculate contribution (J), we can take the sub-array B = (a [0], a [1],..., A [X],... A [y]), calculate contribution (j) in B ). Then the problem is converted to the reverse logarithm of the reverse (k-1) subarray after the array after Y + 1 (because a reverse has been used), that is, \ [F (x, k) = \ sum _ {J >=x} ^ {y} contribution (j) + f (y + 1, k-1) \] traversing y = x + 1 ,..., for each value of N, take the minimum f (x, k) in all cases ).

[4] select the minimum f (x, k) in [2] and [3 ).

Program source code

After the above analysis, we can use the bottom to up method to provide the following source code:

 1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <map> 5 #include <set> 6 #include <algorithm> 7 #include <functional> 8 #include <cstdio> 9 #include <cstdlib>10 using namespace std;11 12 // nSwap == nNiXuNumber13 class BubbleSortWithReversals14 {15 public:16     // return the number of nixu with index >= x17     int getCurNiXuNumber(vector<int> A, int x)18     {19         int n = A.size();20         int cnt = 0;21         for (int i = x; i < n; ++i)22         {23             for (int j = 0; j < i; ++j)24             {25                 if (A[j] > A[i])26                 {27                     cnt++;28                 }29             }30         }31 32         return cnt;33     }34 35     // DP solution:36     // Define: f(x, k) = the number of nixu with indices i >= x that can reverse37     //         at most k subarray without overlap, thea number of xinu at index i,38     //         is the number of index j with j < i && A[j] > A{i]39     //40     //         Then the f(0, K) is the answer of original problem41     //42     // Base Case: f(n, k) = 0 with k = 0, 1, 2, ... MAX_K;43     // Recursive relationship:44     // Case 1: A[x] is not in the reversed subarray, which means A[x] stays in index45     //         x after the most k reverses of subarray, Note that the order of elems46     //         A[j] with j < x do not affect the the number of Nixu at index x47     //         So in this case48     //         f(x, k) = The number of nixu at index x + f(x + 1, k)49     // Case 2: A[x] is in the reversed subarray, we only need to consider the reversed      50     //            subarray (A[x], A[x+1], ..., A[y-1], A[y]), cause if the reversing 51     //         start before index x such as (A[a], A[b], A[c], A[x], ...), then when52     //         x = a, it equals exactly the situation of current time53     //         So in this Case:54     //         We first revere (A[x], A[x+1], ..., A[y-1], A[y]) to obtain55     //         (A[0],...A[x-1], A[y], A[y-1], ..., A[x+1], A[x])56     //         Then we caculate The number of nixu at index x + f(y+1, k-1)57     //         f(x, k) = the number of nixu at x + f(y + 1, k - 1);58     // Compare case 1 and case 2 to get the minimum59 60 61     int getMinSwaps(vector<int> A, int K)62     {63         int n = A.size();64         int f[MAX_K][MAX_K] = {0};    65         // init66         for (int k = 0; k < MAX_K; ++k) f[n][k] = 0;67 68         //69         for (int x = n - 1; x >= 0; --x)70         {71             for (int k = 0; k <= K; ++k)72             {73                 // Case 1: x not in the reversed subarray74                 vector<int> B1(A.begin(), A.begin() + x + 1);75                 f[x][k] = getCurNiXuNumber(B1, x) + f[x+1][k];76 77                 // Case 2: x in the reversed subarray78                 if (k >= 1)79                 {80                     for (int y = x + 1; y < n; ++y)81                     {82                         vector<int> B2(A.begin(), A.begin() + y + 1);83                         reverse(B2.begin() + x, B2.begin() + y + 1);84                         f[x][k] = min(f[x][k],85                                       getCurNiXuNumber(B2, x) + f[y+1][k-1]);86                     }87                 }88             }89         }90 91         return f[0][K];92     }93 public:94     static const int MAX_K = 51;95 };
Complexity Analysis

The time complexity of the subfunction to obtain the current reverse logarithm is O (n ^ 2), and the outer ring of the primary function is NK times. For Case 1, only the contribution at X needs to be calculated, therefore, the subfunction complexity here is O (n). For Case 2, The subfunction needs to be calculated in X ,..., Y contribution, and I (x <= I <= y) must be cyclically, the complexity is $ \ sum _ {Y = x + 1} ^ {Y <n} \ sum _ {I = x} ^ {y} I = O (N ^ 2) $, so the total time complexity is O (NK ^ 3) When case2 occurs ).

References

[1] topcoder editorial SRM 627

[2] Dynamic Programming

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.