Quadrilateral optimized dp

Source: Internet
Author: User

Quadrilateral optimized dp

------------------------------------

The most expensive value is represented by d [I, j ].
D [I, j] = min {d [I, k-1] + d [k + 1, j]} + w [I, j]
W [I, j] = sum [I, j]
Quadrilateral Inequality
W [a, c] + w [B, d] <= w [B, c] + w [a, d] ( Monotonic decision
W [I, j] <= w [I ', J'] ([I, j] belongs to [I', J '])
So we have the following three theorems:

Theorem 1: If w satisfies both the Quadrilateral inequality and the monotonicity of decision-making, d also satisfies the Quadrilateral inequality.
Theorem 2: when the condition of Theorem 1 is met, let d [I, j] Take k of the minimum value as K [I, j], then K [I, j-1] <= K [I, j] <= K [I + 1, j]
Theorem 3: w is convex and only when w [I, j] + w [I + 1, j + 1] <= w [I + 1, j] + w [I, j + 1]

Judging whether a w is convex means judging whether the value of w [I, j + 1]-w [I, j] decreases with the increase of I.
So K [I, j] is only related to K [I + 1, j] and K [I, J-1] When K is obtained, therefore, we can use the ascending I-j order to recursively calculate the final result of each state value and convert O (n ^ 3) to O (n ^ 2)

Certificate --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Note:

Pay attention to the monotonic order of decision-making, which must be consistent with the decision tonality and meaning (!!!!)
Pay attention to the enumeration order. Based on the dp equation and the monotonic equation of decision-making
Pay attention to initialization to prevent access to the invalid or unprocessed status. Initialize the dp and s boundaries, especially the last and next stages of decision-making.

Example 1:

Sharding problem: hdu 3506

Dp [I] [j] = min {dp [I] [k] + dp [k + 1] [j] + cost [I, j]}, I <= k <= j-1, cost [I] [j] = sum [j]-sum [I-1]

S [I] [j-1] <= s [I] [j] <= s [I + 1] [j]

 

// # Pragma warning (disable: 4786) // # pragma comment (linker,/STACK: 16777216) // HEAD # include
 
  
# Include
  
   
# Include
   
    
# Include
    
     
# Include
     
      
# Include
      
        # Include
       
         # Include
        
          # Include
         # Include
          
            # Include
           
             # Include
            
              # Include using namespace std; // LOOP # define FE (I, a, B) for (int I = (a); I <= (B); ++ I) # define FD (I, B, a) for (int I = (B); I >= (a); -- I) # define REP (I, N) for (int I = 0; I <(N); ++ I) # define CLR (A, value) memset (A, value, sizeof ()) # define CPY (a, B) memcpy (a, B, sizeof (a) # define FC (it, c) for (_ typeof (c ). begin () it = (c ). begin (); it! = (C ). end (); it ++) // INPUT # define RI (n) scanf (% d, & n) # define RII (n, m) scanf (% d, & n, & m) # define RIII (n, m, k) scanf (% d, & n, & m, & k) # define RS (s) scanf (% s, s) // OUTPUT # define WI (n) printf (% d, n) # define WS (s) printf (% s, s) typedef long LL; const int INF = 1000000007; const double eps = 1e-10; const int maxn = 2010; int dp [maxn] [maxn], s [maxn] [maxn]; int w [maxn] [maxn]; int n, m; int val [maxn]; int sum [Maxn]; // obtain the minimum dp value // The enumerated range ranges from small to large void solve () {// memset (dp, 0, sizeof (dp )); /// initialization invalid value FE (I, 1, 2 * n) {dp [I] [I] = 0; s [I] [I] = I; /// initialization decision next session, 0} FE (len, 2, n) {for (int I = 2 * n-len; I> = 1; I --) {int j = I + len-1; dp [I] [j] = INF; int a = s [I] [j-1], B = s [I + 1] [j]; int cost = sum [j]-sum [I-1]; for (int k = a; k <= B; k ++) {if (dp [I] [j]> dp [I] [k] + dp [k + 1] [j] + cost) {dp [I] [j] = dp [I] [k] + dp [k + 1] [j] + cost; s [I] [j] = k ;}}} int main () {while (~ RI (n) {FE (I, 1, n) RI (val [I]), val [I + n] = val [I]; FE (I, 1, 2 * n) sum [I] = sum [I-1] + val [I]; // pre (); solve (); int ans = INF; FE (I, 1, n) {if (ans> dp [I] [n + I-1]) ans = dp [I] [n + I-1];} printf (% d, ans);} return 0 ;}
            
           
          
        
       
      
     
    
   
  
 

Example 2: Post Office problems:

 

Poj 1160

1: note that the order of I and j in this method is different from that in normal cases.

The decision interval is: s [I-1] [j] <= s [I] [j] <= s [I] [j + 1] (!).

For details, see notes:

// # Pragma warning (disable: 4786) // # pragma comment (linker,/STACK: 16777216) // HEAD # include
 
  
# Include
  
   
# Include
   
    
# Include
    
     
# Include
     
      
# Include
      
        # Include
       
         # Include
        
          # Include
         # Include
          
            # Include
           
             # Include
            
              # Include using namespace std; // LOOP # define FE (I, a, B) for (int I = (a); I <= (B); ++ I) # define FD (I, B, a) for (int I = (B); I >= (a); -- I) # define REP (I, N) for (int I = 0; I <(N); ++ I) # define CLR (A, value) memset (A, value, sizeof ()) # define CPY (a, B) memcpy (a, B, sizeof (a) # define FC (it, c) for (_ typeof (c ). begin () it = (c ). begin (); it! = (C ). end (); it ++) // INPUT # define RI (n) scanf (% d, & n) # define RII (n, m) scanf (% d, & n, & m) # define RIII (n, m, k) scanf (% d, & n, & m, & k) # define RS (s) scanf (% s, s) // OUTPUT # define WI (n) printf (% d, n) # define WS (s) printf (% s, s) typedef long LL; const int INF = 1000000007; const double eps = 1e-10; const int maxn = 1000010; int dp [33] [333], s [33] [333]; int w [333] [333]; int n, m; int val [333]; int sum [333];/ // Dp [I] [j] = min {dp [I-1] [k] + w [k + 1] [j]}, i-1 <= k <= j-1 // General requirements I <= j (!!) // S [I-1] [j] <= s [I] [j] <= s [I] [j + 1] (!) /// Pay attention to the monotonic order of decision-making, which must be consistent with the decision tonality and meaning (!!!!) /// Pay attention to the enumeration order, and initialize Based on the dp equation and the monotonic equation of decision. // pay attention to initialization to prevent access to invalid or unprocessed states. Initialize the dp and s boundaries, especially the last and next stages of decision-making. Void pre () {for (int I = 1; I <= n; I ++) // here is a recursive formula for preprocessing {w [I] [I] = 0; for (int j = I + 1; j <= n; j ++) {int mid = (j + I)> 1; w [I] [j] = w [I] [j-1] + val [j]-val [mid]; // int x = sum [j]-sum [mid]-val [mid] * (j-mid ); // x + = val [mid] * (mid-I)-(sum [mid-1]-sum [I-1]) ;}} /// obtain the minimum dp value // enumerate I from small to large // then enumerate j from large to small void solve () {memset (dp, 0, sizeof (dp); // initialize the invalid FE (I, 1, n) {dp [1] [I] = w [1] [I]; s [1] [I] = 0; // initialization decision next, 0} FE (I, 2, m) {// s [1] [I] = 0; s [I] [n + 1] = n; // initialize the previous decision for (int j = n; j> = I; j --) {int tmp = dp [I] [j] = INF; // initialize the optimal value int a = s [I-1] [j], B = s [I] [j + 1]; // a = max (a, I-1); B = min (B, j-1 ); // I-1 <= k <= j-1 for (int k = a; k <= B; k ++) // ensure that all enumerated values are valid, {if (tmp> dp [I-1] [k] + w [k + 1] [j]) {tmp = dp [I-1] [k] + w [k + 1] [j]; s [I] [j] = k ;}} Dp [I] [j] = tmp ;}} int main () {while (~ RII (n, m) {FE (I, 1, n) RI (val [I]), sum [I] = sum [I-1] + val [I]; pre (); solve (); printf (% d, dp [m] [n]);} return 0 ;}
            
           
          
        
       
      
     
    
   
  
 

2:-For details, see annotations.

The decision interval is: s [I] [j-1] <= s [I] [j] <= s [I + 1] [j] (!).

 

// # Pragma warning (disable: 4786) // # pragma comment (linker,/STACK: 16777216) // HEAD # include
 
  
# Include
  
   
# Include
   
    
# Include
    
     
# Include
     
      
# Include
      
        # Include
       
         # Include
        
          # Include
         # Include
          
            # Include
           
             # Include
            
              # Include using namespace std; // LOOP # define FE (I, a, B) for (int I = (a); I <= (B); ++ I) # define FD (I, B, a) for (int I = (B); I >= (a); -- I) # define REP (I, N) for (int I = 0; I <(N); ++ I) # define CLR (A, value) memset (A, value, sizeof ()) # define CPY (a, B) memcpy (a, B, sizeof (a) # define FC (it, c) for (_ typeof (c ). begin () it = (c ). begin (); it! = (C ). end (); it ++) // INPUT # define RI (n) scanf (% d, & n) # define RII (n, m) scanf (% d, & n, & m) # define RIII (n, m, k) scanf (% d, & n, & m, & k) # define RS (s) scanf (% s, s) // OUTPUT # define WI (n) printf (% d, n) # define WS (s) printf (% s, s) typedef long LL; const int INF = 1000000007; const double eps = 1e-10; const int maxn = 1000010; int dp [333] [33], s [333] [33]; int w [333] [333]; int n, m; int val [333]; int sum [333];/ // Dp [I] [j] = min {dp [k] [j-1] + w [k + 1] [j]}, j-1 <= k <= I-1 // here I> = j // s [I] [j-1] <= s [I] [j] <= s [I + 1] [j] (!) /// Pay attention to the monotonic order of decision-making, which must be consistent with the decision tonality and meaning (!!!!) /// Pay attention to the enumeration order, and initialize Based on the dp equation and the monotonic equation of decision. // pay attention to initialization to prevent access to invalid or unprocessed states. Initialize the dp and s boundaries, especially the last and next stages of decision-making. Void pre () {for (int I = 1; I <= n; I ++) // here is a recursive formula for preprocessing {w [I] [I] = 0; for (int j = I + 1; j <= n; j ++) {int mid = (j + I)> 1; w [I] [j] = w [I] [j-1] + val [j]-val [mid] ;}} /// obtain the minimum dp value // enumerate I from small to large // then enumerate j from large to small void solve () {memset (dp, 0, sizeof (dp); // initialize the invalid FE (I, 1, n) {dp [I] [1] = w [1] [I]; s [I] [1] = 0; // initialization decision next time, 0} FE (I, 2, m) {// s [I] [1] = 0; s [n + 1] [I] = n; // initialize the previous decision for (int j = n; j> = I; j --) {int tmp = dp [j] [I] = INF; // initialize the optimal value int a = s [j] [I-1], B = s [j + 1] [I]; // a = max (a, I-1); B = min (B, j-1 ); for (int k = a; k <= B; k ++) // ensure that all enumerated values are valid, {if (tmp> dp [k] [I-1] + w [k + 1] [j]) {tmp = dp [k] [I-1] + w [k + 1] [j]; s [j] [I] = k ;}} dp [j] [I] = tmp ;}} int main () {while (~ RII (n, m) {FE (I, 1, n) RI (val [I]); pre (); solve (); printf (% d, dp [n] [m]);} return 0 ;}
            
           
          
        
       
      
     
    
   
  
 


 

Certificate ------------------------------------------- certificate --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Then, the decision interval is s [I-1] [j] <= s [I] [j] <= s [I] [j + 1] (!).

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.