确定状态
result[i][j][1]:表示合并i到j的所有石子的最高得分
result[i][j][0]:表示合并i到j的所有石子的最低得分
状态转移方程
result[i][j][0] = min(result[i][j][0], result[i][k][0] + result[k+1][j][0] + cost(i,j) );
result[i][j][1] = max(result[i][j][1], result[i][k][1] + result[k+1][j][1] + cost(i,j) );
边界条件
result[i][i][0] = result[i][i][1] = 0;
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <string.h>
#include <math.h>
#include <stack>
#include <ctype.h>
using namespace std;
string str;
int n;
int result[105][105][2];
int num[105];
int Min = (1<<30);
int Max = (-1)*(1<<30);
int cost(int i, int j)
{
int sum = 0;
for( int k = i; k <= j; k++ )
sum += num[k];
return sum;
}
void dp()
{
for( int i = 1; i <= n; i++ )
result[i][i][0] = result[i][i][1] = 0;//边界条件
for( int l = 2; l <= n; l++ )
{
for( int i = 1; i+l-1 <= n; i++ )
{
int j = i+l-1;
int extra = cost(i, j);
for( int k = i; k < j; k++)
{
result[i][j][0] = min(result[i][j][0], result[i][k][0] + result[k+1][j][0] + extra );
result[i][j][1] = max(result[i][j][1], result[i][k][1] + result[k+1][j][1] + extra );
}
}
}
Max = max(Max, result[1][n][1]);
Min = min(Min, result[1][n][0]);
}
int main()
{
while( cin >> n )
{
Min = (1<<30);
Max = (-1)*(1<<30);
for( int i = 1; i <= n; i++ )
{
cin >> num[i];
for(int j = 1; j <= n; j++ )
{
result[i][j][0] = (1<<30);
result[i][j][1] = -(1<<30);
}
}
dp();
cout << Min << ' ' << Max << endl;
}
return 0;
}