OJ题目:click here~~
题目分析:分别给出n个线段的长度,求用这些线段能围成的三角形面积的最大值。
双线性dp。设dp[ i ][ j ] 当能得到 边长i 和 j 时,dp[ i ][ j ] = 1 , 否则为0;此处不需要判断能否构成三角形。
dp[ i ][ j ] = dp[ i ][ j ] || dp[ i - x[ k ] ][ j ] || dp[ i ][ j - x[ k ] ]
AC_CODE
const int max_n = 42;
int Area(int i ,int j,int k)
{
if((i + j) > k && (i + k) > j && (j + k) > i)
{
double p = 0.5 * (i + j + k) ;
return (int)(100.0 * sqrt(1.0*p*(p-i)*(p-j)*(p-k))) ;
}
else
return -1;
}
int dp[(max_n*max_n)>>1][(max_n*max_n)>>1];
int main(){
//freopen("in.txt","r",stdin);
int n;
while(cin >> n)
{
int i , j ,k, x[max_n] , sum = 0 ,s;
memset(dp , 0 , sizeof(dp));
for(i = 1;i <= n;i++)
{
scanf("%d",&x[i]);
sum += x[i];
}
s = sum >> 1;
dp[0][0] = 1;
for(k = 1;k <= n;k++)
for(i = s;i >= 0;i--)
for(j = i;j >= 0;j--)
{
if(i >= x[k])
dp[i][j] |= dp[i - x[k]][j];
if(j >= x[k])
dp[i][j] |= dp[i][j - x[k]];
}
int ans = -1;
for(i = 1;i <= s;i++)
for(j = 1;j <= s;j++)
if(dp[i][j])
{
ans = max(ans , Area(i , j , sum - i - j));
}
cout << ans << endl;
}
return 0 ;
}