石子合并
怒贴代码:
1 #include<cstdio> 2 #define INF 199999999 3 int n , m, i, j, l, k, an1 = INF, an2 = -INF, Min[ 2002][ 2002], Max[ 2002][ 2002], w[ 2002][ 2002], h[ 2002]; 4 inline void MAX(int &num1,int num2, int num3){ if (num2>num3) num1=num2; else num1=num3; num1+=h[j]-h[i-1];} 5 inline void MIN(int &num1,int num2){ if (num2<num1) num1=num2, w[ i][ j]=k;} 6 int main ( ) 7 { 8 scanf( "%d", &n); m = 2 * n - 1 ; 9 for ( i = 1; i <= n; i++) scanf( "%d", &h[ i]), h[ i+n] = h[ i]; 10 for ( i = 1; i <= m; i++) h[ i] += h[ i-1], w[ i][ i] = i; 11 for ( l = 1; l < n ; l++) 12 for ( i = 1; i <= m-l; i++) 13 { 14 j = i + l, Min[ i][ j] = INF; 15 for ( k = w[ i][ j-1]; k <= w[ i+1][ j]; k++) 16 MIN( Min[ i][ j], Min[ i][ k]+ Min[ k+1][ j]); Min[ i][ j] += h[ j]-h[ i-1]; 17 MAX( Max[ i][ j], Max[ i][ i]+ Max[ i+1][ j] , Max[ i][ j-1] + Max[ j][ j]); 18 } for ( i = 1; i <= m-n+1; i++) if ( Max[ i][ i+n-1] > an2) an2 = Max[ i][ i+n-1]; 19 for ( i = 1; i <= m-n+1; i++) MIN( an1, Min[ i][ i+n-1]); printf( "%d\n%d", an1, an2); 20 }