题意是,把很多单独的线段重新组合成一个三角形,使得三角形面积最大。所有的线段都必须用上。
解法是动态规划。
用背包的思路,dp[i][j]为1,表示从这些线段中可以组成一个边长为i,另一边为j的三角形;为0则表示不能。
因为周长是一定的,所以dp[i][j]表示一个三角形的边分别是i,j,c-i-j,通过海伦公式就能算出面积。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
bool check[1000][1000];
double check_and_calc_the_area(int a,int b,int c,double &t)
{
double q;
if (a+b <= c || a+c <= b || b+c <= a)
return false;
q=(a+b+c)/2.0;
t=sqrt(q*(q-a)*(q-b)*(q-c));
t*=100;
return true;
}
int main()
{
int hc,i,j,k,c,l[50],n,ans;
double t;
scanf("%d",&n);
c=0;
for (i=0; i<n; i++)
{
scanf("%d",l+i);
c+=l[i];
}
hc=c>>1;
memset(check,false,sizeof(check));
check[0][0]=true;
for (i=0; i<n; i++)
{
for (j=hc; j>=0; j--)
{
for (k=hc; k>=0; k--)
{
if (j >= l[i])
{
if (check[j-l[i]][k])
check[j][k]=true;
}
if (k >= l[i])
{
if (check[j][k-l[i]])
check[j][k]=true;
}
}
}
}
ans=0;
for (i=1; i<=hc; i++)
{
for (j=1; j<=hc; j++)
{
if (check[i][j] == true)
{
if (check_and_calc_the_area(i,j,c-i-j,t) == true)
ans=(int)t>ans?(int)t:ans;
}
}
}
printf("%d",ans==0?-1:ans);
}