携程的第二场第二题,比赛时被水过去了。。。
题目给一些木棒,要求全部用上形成三条边,问能形成的三角形最大面积是多少?
题意很明确,只需要确定所有能形成的边的组合,再从这些组合中求最大值即可。
用二维数组dp[i][t]表示边长分别为i和t,两边确定,第三条边边长为sum-i-t,然后就是背包确定能否形成i和t两条边的过程了。
很简单的二维背包,比赛时看出来是背包,没想到这点,以至于花了大把时间去水掉,还是做过的题目太少。
代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
int dp[801][801];
int a[41];
int n;
double sum;
bool sap(int a,int b,int c)
{
if (a+b>c&&a+c>b&&b+c>a)
return true;
return false;
}
int s(int a,int b,int c)
{
double ss=sum/2;
ss=ss*(ss-a)*(ss-b)*(ss-c);
ss=sqrt(ss)*100;
int t=ss;
return t;
}
int main()
{
while (~scanf("%d",&n))
{
sum=0;
for (int i=0;i<n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for (int i=0;i<n;i++)
{
for (int t=sum/2;t>=0;t--)
{
for (int k=sum/2;k>=0;k--)
{
if ((t>=a[i]&&dp[t-a[i]][k])||(k>=a[i]&&dp[t][k-a[i]]))
dp[t][k]=1;
}
}
}
int m=-1;
for (int i=0;i<=sum/2;i++)
{
for (int t=0;t<=sum/2;t++)
{
if (dp[i][t]&&sap(i,t,sum-i-t))
{
int cur=s(i,t,sum-i-t);
m=m>cur?m:cur;
}
}
}
printf("%d\n",m);
}
}