题目大意:给定一些棍子求这些棍子能够组成的三角形的最大面积。
解题思路:这里要利用三角形的面积公式
p = (a + b + c) / 2, 周长的一半
三角形面积 = sqrt(p * (p - a) * (p - b) * (p - c))
dp[k][i][j]表示前k根棍子,边长为i和j是否能组成一个三角形。
所以dp[k][i][j] = dp[k-1][i - edge[k]][j] | dp[k-1][i][j - edge[k]]; 其中要求 i >= edge[k], j >= edge[k];
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 810;
bool dp[maxn][maxn];
int s, n, edge[maxn];
int main()
{
while(scanf("%d", &n) != EOF)
{
memset(dp, 0, sizeof(dp));
s = 0;
for(int i = 0; i < n; i++)
{
scanf("%d", &edge[i]);
s += edge[i];
}
int mid = s >> 1;
dp[0][0] = true;
for(int i = 0; i < n; i++)
{
for(int j = mid; j >= 0; j--)
{
for(int k = j; k >= 0; k--)
{
if(edge[i] <= j)
dp[j][k] |= dp[j - edge[i]][k];
if(edge[i] <= k)
dp[j][k] |= dp[j][k - edge[i]];
}
}
}
double half = s / 2.0;
double ans = -1;
for(int i = 0; i < mid; i++)
{
for(int j = 0; j <= i; j++)
{
if(dp[i][j])
{
int k = s - i - j;
if(i + j > k && i + k > j && j + k > i) //两边之和大于第三边
ans = max(ans, half * (half - i) * (half - j) * (half - k));
}
}
}
if(-1 == ans)
printf("-1\n");
else
printf("%d\n", (int)(sqrt(ans) * 100));
}
return 0;
}