zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    禁用网络连接后无法访问本机数据库的问题
    DevExpress使用笔记
    DEV控件 皮肤问题
    SQLServer2008导入Excel遇到的问题
    InnoSetup使用笔记
    SQLServer清空数据库中所有表的数据
    MS SQL Server2000转换成MySQL
    由MySQL登录不了引发的一些问题
    onerror事件
    DIV+CSS一些小小的技巧
  • 原文地址:https://www.cnblogs.com/DevinZ/p/4411449.html
Copyright © 2011-2022 走看看