题意:给出一些木棍,必须全都用上,问能拼成的最大的三角形面积是多少。

分析:动态规划,f[i][j][k]表示用前i根木棍能否构成两条长度分别为j,k的边。

f[i][j][k] = f[i - 1][j][k];
if (j >= fence[i])
   f[i][j][k] = f[i][j][k] || f[i - 1][j - fence[i]][k];
if (k >= fence[i])
   f[i][j][k] = f[i][j][k] || f[i - 1][j][k - fence[i]];

以上过程只是构成两条边,第三条边的长度可以用总长度减去前两条边得到。 之前没有考虑这三条边是否能构成三角形。然后枚举所有的f[n][i][j]看能否构成三角形,并更新最大面积即可。

poj1948_iospoj1948_#define_02View Code
#include <iostream>
#include
<cstdio>
#include
<cstdlib>
#include
<cstring>
#include
<cmath>
usingnamespace std;

#define maxn 41

int fence[maxn];
bool f[maxn][805][805];
int sum =0, n;

bool ok(int a, int b)
{
int c = sum - a - b;
if (c < a + b && c > abs(a - b))
returntrue;
returnfalse;
}

double area(int a, int b, int c)
{
double p = sum /2.0;
return sqrt(p * (p - a) * (p - b) * (p - c));
}

int main()
{
//freopen("t.txt", "r", stdin);
scanf("%d", &n);
for (int i =1; i <= n; i++)
{
scanf(
"%d", &fence[i]);
sum
+= fence[i];
}
memset(f,
0, sizeof(f));
f[
0][0][0] =true;
for (int i =1; i <= n; i++)
for (int j =0; j <= sum /2; j++)
for (int k =0; k <= sum /2; k++)
{
f[i][j][k]
= f[i -1][j][k];
if (j >= fence[i])
f[i][j][k]
= f[i][j][k] || f[i -1][j - fence[i]][k];
if (k >= fence[i])
f[i][j][k]
= f[i][j][k] || f[i -1][j][k - fence[i]];
}
double ans =-1;
for (int i =1; i <= sum /2; i++)
for (int j =1; j <= sum /2; j++)
if (f[n][i][j] && ok(i, j))
ans
= max(ans, area(i, j, sum - i - j));
if (ans >0)
ans
*=100;
printf(
"%d\n", (int)ans);
return0;
}