Introduction to Divide-and-Conquer

 

1. Recursion

  According to wikipedia,  Recursion is the process of repeating itself in a self-similar way. A good case in point is the procedure of Euclidean Algorithm:

 1     public static int gcd(int m,int n,int[] ref) {
 2         // Calculate the greatest common divisor of m and n
 3         // Precondition: n>=0 && m>0 && ref.length>=2
 4         // Postcondition: the gcd of m and n is returned
 5         //        and gcd(m,n) = m*ref[0]+n*ref[1]
 6         if (n==0) {
 7             ref[0] = 1;
 8             ref[1] = 0;
 9             return m;
10         } else {
11             int val = gcd(n,m%n,ref);
12             int y = ref[1];
13             ref[1] = ref[0]-m/n*y;
14             ref[0] = y;
15             return val;
16         }
17     }

 

 

2. Divide-and-Conquer Algorithms

  Sometimes it is entirely possible for us to gain a better time performance if we divide the problem into several sub-problems and solve them recursively before finally accomplishing the total task. This is what we call the family of Divide-and-Conquer Algorithms, and I shall give you some examples:

  (1)  To calculate the nth power of a natural number x, instead of multiplying x to the temporary result repeatedly, we'd better use the following method:

 1     public static long pow(int x,int n) {
 2         // Return the nth power of a natural number x
 3         if (n==0) {
 4             return 1;
 5         } else {
 6             long tmp = pow(x,n>>1);
 7             if ((n&1)!=0) {
 8                 return tmp*tmp*x;
 9             } else {
10                 return tmp*tmp;
11             }
12         }
13     }

  (2)  Some sorting algorithms, such as Quick Sort, Merge Sort and so forth.

  (3)  Multiplication of two big integers, a trick invented by Gauss.

  (4)  Multiplication of two big matrices, what is called Strassen Algorithm.

  (5)  Multiplication of two polynomials, the well-known Fast Fourier Transform.

  (6)  Determining the nearest point pair among all the given points in a plane.


3. Master Theorem

  To determine the time complexity of a divide-and-conquer algorithm remains to be a tricky work since some recursions are strikingly intractable. Whereas there is a theorem that can assist us a lot in most cases. The following figure is by courtesy of the renowned algorithm cookbook CLRS:

 

                                                         

 

4. My Solution to USACO Problem "rect1"

  Here I wish to show you an example that I used a divide-and-conquer method to solve a USACO training problem called Shaping Regions:

 1 import java.io.*;
 2 import java.util.*;
 3 
 4 public class rect1 {
 5     public static Scanner input;
 6     public static PrintWriter output;
 7     public static int num;        // number of rectangles
 8     public static int [] color;        //  areas of different colors
 9     public static int [][] rect;        // rectangle information
10     
11     public static int cover(int i,int x1,int y1,int x2,int y2) {
12         // The area of Rect(x1,y1,x2,y2) that is not covered
13         //        by any one from Rect[i] to Rect[num]
14         if (x1>=x2||y1>=y2) {
15             return 0;
16         } else if (i>num) {
17             return (x2-x1)*(y2-y1);
18         }
19         // calculate the overlapping part Rect(a,b,c,d)
20         int a = (rect[i][0]>x1)? rect[i][0]:x1;
21         int b = (rect[i][1]>y1)? rect[i][1]:y1;
22         int c = (rect[i][2]<x2)? rect[i][2]:x2;
23         int d = (rect[i][3]<y2)? rect[i][3]:y2;
24         if (a>=c || b>=d)  {
25             // no overlapping area
26             return cover(i+1,x1,y1,x2,y2);
27         } else {
28             // divide the remaining part into 8 parts
29             int val = 0;
30             val += cover(i+1,x1,y1,a,b);
31             val += cover(i+1,a,y1,c,b);
32             val += cover(i+1,c,y1,x2,b);
33             val += cover(i+1,c,b,x2,d);
34             val += cover(i+1,c,d,x2,y2);
35             val += cover(i+1,a,d,c,y2);
36             val += cover(i+1,x1,d,a,y2);
37             val += cover(i+1,x1,b,a,d);
38             return val;
39         }
40     }
41     public static void getInput() throws IOException {
42         // Get the input data:
43         input = new Scanner(new FileReader("rect1.in"));
44         color = new int [2500];
45         int wid = input.nextInt();
46         int len = input.nextInt();
47         num = input.nextInt();
48         rect = new int [num+1][5];
49         //    consider background as Rect[0]
50         rect[0][2] = wid;
51         rect[0][3] = len;
52         for (int i=1;i<=num;i++) {
53             // following info of  rectangles
54             rect[i][0] = input.nextInt();
55             rect[i][1] = input.nextInt();
56             rect[i][2] = input.nextInt();
57             rect[i][3] = input.nextInt();
58             rect[i][4] = input.nextInt()-1;    // color
59         }
60         input.close();
61     }
62     public static void printAns() throws IOException {
63         // Print the final answer:
64         output = new PrintWriter(new FileWriter("rect1.out"));
65         for (int i=0;i<2500;i++) {
66             if (color[i]>0) {
67                 output.println(i+1+" "+color[i]);
68             }
69         }
70         output.close();
71     }
72     public static void main(String[] args) throws IOException {
73         getInput();
74         for (int i=0;i<num;i++) {
75             // the area of Rect[i] that can be shown ultimately
76             color[rect[i][4]] += 
77                     cover(i+1,rect[i][0],rect[i][1],rect[i][2],rect[i][3]);
78         }
79         // the top rectangle is covered by none
80         color[rect[num][4]] += 
81                 (rect[num][2]-rect[num][0])*(rect[num][3]-rect[num][1]);
82         printAns();
83     }
84 } 

 

 

References:

  1. Cormen, T. H. et al. Introduction to Algorithms[M]. 北京:机械工业出版社,2006-09

  2. Dasgupta, Sanjoy, Christos Papadimitriou, and Umesh Vazirani. Algorithms[M].北京:机械工业出版社,2009-01-01

 

posted on 2015-03-20 21:19  DevinZ  阅读(151)  评论(0编辑  收藏  举报

导航