Array 
      
    
      
      
      
        Dynamic Programming 
      
    
      
      
      
        Memoization 
      
    
   
  
    
      
       
     
  
  
    
      
    
    
      
       
     
  
Description 
You are given several boxes with different colors represented by different positive numbers.
You may experience several rounds to remove boxes until there is no box left. Each time you can choose some continuous boxes with the same color (i.e., composed of k boxes, k >= 1), remove them and get k * k points.
Return the maximum points you can get .
 
Example 1: 
Input:  boxes = [1,3,2,2,2,3,4,3,1]
Output:  23
Explanation: 
[1, 3, 2, 2, 2, 3, 4, 3, 1] 
----> [1, 3, 3, 4, 3, 1] (3*3=9 points) 
----> [1, 3, 3, 3, 1] (1*1=1 points) 
----> [1, 1] (3*3=9 points) 
----> [] (2*2=4 points)
 
Example 2: 
Input:  boxes = [1,1,1]
Output:  9
 
Example 3: 
Input:  boxes = [1]
Output:  1
 
 
Constraints: 
    1 <= boxes.length <= 100 
    1 <= boxes[i] <= 100 
 
Solutions 
Solution 1 
Python3 Java C++ Go 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 class   Solution : 
    def   removeBoxes ( self ,  boxes :  List [ int ])  ->  int : 
        @cache 
        def   dfs ( i ,  j ,  k ): 
            if  i  >  j : 
                return  0 
            while  i  <  j  and  boxes [ j ]  ==  boxes [ j  -  1 ]: 
                j ,  k  =  j  -  1 ,  k  +  1 
            ans  =  dfs ( i ,  j  -  1 ,  0 )  +  ( k  +  1 )  *  ( k  +  1 ) 
            for  h  in  range ( i ,  j ): 
                if  boxes [ h ]  ==  boxes [ j ]: 
                    ans  =  max ( ans ,  dfs ( h  +  1 ,  j  -  1 ,  0 )  +  dfs ( i ,  h ,  k  +  1 )) 
            return  ans 
        n  =  len ( boxes ) 
        ans  =  dfs ( 0 ,  n  -  1 ,  0 ) 
        dfs . cache_clear () 
        return  ans 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 class  Solution   { 
     private   int [][][]   f ; 
     private   int []   b ; 
     public   int   removeBoxes ( int []   boxes )   { 
         b   =   boxes ; 
         int   n   =   b . length ; 
         f   =   new   int [ n ][ n ][ n ] ; 
         return   dfs ( 0 ,   n   -   1 ,   0 ); 
     } 
     private   int   dfs ( int   i ,   int   j ,   int   k )   { 
         if   ( i   >   j )   { 
             return   0 ; 
         } 
         while   ( i   <   j   &&   b [ j ]   ==   b [ j   -   1 ] )   { 
             -- j ; 
             ++ k ; 
         } 
         if   ( f [ i ][ j ][ k ]   >   0 )   { 
             return   f [ i ][ j ][ k ] ; 
         } 
         int   ans   =   dfs ( i ,   j   -   1 ,   0 )   +   ( k   +   1 )   *   ( k   +   1 ); 
         for   ( int   h   =   i ;   h   <   j ;   ++ h )   { 
             if   ( b [ h ]   ==   b [ j ] )   { 
                 ans   =   Math . max ( ans ,   dfs ( h   +   1 ,   j   -   1 ,   0 )   +   dfs ( i ,   h ,   k   +   1 )); 
             } 
         } 
         f [ i ][ j ][ k ]   =   ans ; 
         return   ans ; 
     } 
} 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 class   Solution   { 
public : 
     int   removeBoxes ( vector < int >&   boxes )   { 
         int   n   =   boxes . size (); 
         vector < vector < vector < int >>>   f ( n ,   vector < vector < int >> ( n ,   vector < int > ( n ))); 
         function < int ( int ,   int ,   int ) >   dfs ; 
         dfs   =   [ & ]( int   i ,   int   j ,   int   k )   { 
             if   ( i   >   j )   return   0 ; 
             while   ( i   <   j   &&   boxes [ j ]   ==   boxes [ j   -   1 ])   { 
                 -- j ; 
                 ++ k ; 
             } 
             if   ( f [ i ][ j ][ k ])   return   f [ i ][ j ][ k ]; 
             int   ans   =   dfs ( i ,   j   -   1 ,   0 )   +   ( k   +   1 )   *   ( k   +   1 ); 
             for   ( int   h   =   i ;   h   <   j ;   ++ h )   { 
                 if   ( boxes [ h ]   ==   boxes [ j ])   { 
                     ans   =   max ( ans ,   dfs ( h   +   1 ,   j   -   1 ,   0 )   +   dfs ( i ,   h ,   k   +   1 )); 
                 } 
             } 
             f [ i ][ j ][ k ]   =   ans ; 
             return   ans ; 
         }; 
         return   dfs ( 0 ,   n   -   1 ,   0 ); 
     } 
}; 
 
 
 1 
 2 
 3 
 4 
 5 
 6 
 7 
 8 
 9 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 func   removeBoxes ( boxes   [] int )   int   { 
     n   :=   len ( boxes ) 
     f   :=   make ([][][] int ,   n ) 
     for   i   :=   range   f   { 
         f [ i ]   =   make ([][] int ,   n ) 
         for   j   :=   range   f [ i ]   { 
             f [ i ][ j ]   =   make ([] int ,   n ) 
         } 
     } 
     var   dfs   func ( i ,   j ,   k   int )   int 
     dfs   =   func ( i ,   j ,   k   int )   int   { 
         if   i   >   j   { 
             return   0 
         } 
         for   i   <   j   &&   boxes [ j ]   ==   boxes [ j - 1 ]   { 
             j ,   k   =   j - 1 ,   k + 1 
         } 
         if   f [ i ][ j ][ k ]   >   0   { 
             return   f [ i ][ j ][ k ] 
         } 
         ans   :=   dfs ( i ,   j - 1 ,   0 )   +   ( k + 1 ) * ( k + 1 ) 
         for   h   :=   i ;   h   <   j ;   h ++   { 
             if   boxes [ h ]   ==   boxes [ j ]   { 
                 ans   =   max ( ans ,   dfs ( h + 1 ,   j - 1 ,   0 ) + dfs ( i ,   h ,   k + 1 )) 
             } 
         } 
         f [ i ][ j ][ k ]   =   ans 
         return   ans 
     } 
     return   dfs ( 0 ,   n - 1 ,   0 ) 
} 
 
 
 
 
  
  
  
    
    
    
    
      
  
    
      
  
     
   
  GitHub