http://acm.nankai.edu.cn/p1137.html
http://172.20.16.106/JudgeOnline/showproblem?problem_id=1036
// 7562 liyunsong B Accepted     G++   2009-04-17 12:57:36 
#include < iostream >
using   namespace  std;
const   int  N  =   101 ;
int  dpmax[ 2 * N][ 2 * N]; // dpmax[i][j]表示从第i对石子开始连续顺时针合并j堆的最大耗费  
int  dpmin[ 2 * N][ 2 * N]; // dpmin[i][j]表示从第i对石子开始连续顺时针合并j堆的最小耗费
int  mins[ 2 * N][ 2 * N];
int  maxs[ 2 * N][ 2 * N];
int  num[ 2 * N]; 

int  main()
{
    
int n,i,j,k,r;
    
while(cin>>n)
    
{
        
int t;
        
for(i=1;i<=n;i++)
            scanf(
"%d",&num[i]);

        
if(n==1)
        
{
            printf(
"0\n0\n");
            
continue;
        }
    

        
for(i=1;i<=n;i++)
            num[i
+n] = num[i];

        
for(i=1;i<=2*n;i++)
            
for(j=1;j<=2*n;j++)
            
{
                dpmin[i][j] 
= 10000000;
                dpmax[i][j] 
= 0;
            }


        
for(i=1;i<=2*n;i++)
        
{
            dpmin[i][
1= dpmax[i][1= 0;
            dpmin[i][i] 
= dpmax[i][i] = 0;
            mins[i][i] 
= maxs[i][i] = num[i];
        }


        
for(r = 2;r<=n;r++)//合并堆数
        {
            
for(i=1;i<2*n-r+1;i++)//起点
            {
                j 
= i+r-1;
                dpmin[i][j] 
= dpmin[i+1][j] + num[i] + mins[i+1][j];
                mins[i][j] 
= num[i] + mins[i+1][j];
                dpmax[i][j] 
= dpmax[i+1][j] + num[i] + maxs[i+1][j];
                maxs[i][j] 
= num[i] + maxs[i+1][j];
                
for(k=i+1;k<j;k++)
                
{
                    t 
= mins[i][k] + mins[k+1][j] + dpmin[i][k] + dpmin[k+1][j];
                    
if(t < dpmin[i][j])
                    
{
                        dpmin[i][j] 
= t;
                        mins[i][j] 
= mins[i][k] + mins[k+1][j];
                    }


                    t 
= maxs[i][k] + maxs[k+1][j] + dpmax[i][k] + dpmax[k+1][j];
                    
if(t > dpmax[i][j])
                    
{
                        dpmax[i][j] 
= t;
                        maxs[i][j] 
= maxs[i][k] + maxs[k+1][j];
                    }

                }

            }

        }

        
int MAX = dpmax[1][n];
        
int MIN = dpmin[1][n];
        
for(i=2;i<=n;i++)
        
{
            
if(MAX < dpmax[i][i+n-1])
                MAX 
= dpmax[i][i+n-1];
            
if(MIN > dpmin[i][i+n-1])
                MIN 
= dpmin[i][i+n-1];
        }

        printf(
"%d\n%d\n",MIN,MAX);
    }

    
return 0;
}