题目链接:http://poj.org/problem?id=1948
题目大意:
p.s.跟原题不一样的都删掉了。。不理解的话看poj上的吧
题解:
背包..
f[i][j][k]表示取到第i根木棒,一条边的值取到了j,还有一条边的值取到了k。
转移就是:if f[i-1][j][k] {f[i][j+a[i]][k]=1; f[i][j][k+a[i]]=1;f[i][j][k]=1;}
每次判断能否构成三角形并取面积的最大值。要滚动!
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
int a[50],f[2][1700][1700];
double mymax(double x,double y){return (x>y)?x:y;}
double ss(double x,double y,double z)//海伦公式算面积
{
double p=(x+y+z)/2;
double ret=sqrt(p*(p-x)*(p-y)*(p-z))*100.0;
return ret;
}
bool pd(int x,int y,int z)//判断能否构成三角形
{
if (!(x!=0 && y!=0 && z!=0)) return false;
if (z<x+y && z>abs(x-y)) return true;
return false;
}
int main()
{
//freopen("pasture.in","r",stdin);
//freopen("pasture.out","w",stdout);
int n,i,j,k,t,sum;
scanf("%d",&n);
double ans;sum=0;
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}t=0;ans=-1;//sort(a+1,a+1+n);
memset(f,0,sizeof(f));
f[1][0][0]=1;
for (i=1;i<=n;i++)
{
for (j=0;j<=sum/2;j++)
for (k=0;k<=sum/2;k++)
if (f[1-t][j][k])
{
f[t][j][k]=1;
f[t][j+a[i]][k]=1;
f[t][j][k+a[i]]=1;
if (pd(j+a[i],k,sum-k-j-a[i])) ans=mymax(ans,ss(j+a[i],k,sum-k-j-a[i]));
if (pd(j,k+a[i],sum-k-j-a[i])) ans=mymax(ans,ss(j,k+a[i],sum-k-j-a[i]));
}t=1-t;
}
printf("%d\n",(int)ans);
return 0;
}