题目描述
和所有人一样,奶牛喜欢变化。它们正在设想新造型的牧场。奶牛建筑师Hei想建造围有漂亮白色栅栏的三角形牧场。她拥有N(3≤N≤40)块木板,每块的长度Li(1≤Li≤40)都是整数,她想用所有的木板围成一个三角形使得牧场面积最大。
请帮助Hei小姐构造这样的牧场,并计算出这个最大牧场的面积。
输入输出格式
输入格式:
第1行:一个整数N
第2..N+1行:每行包含一个整数,即是木板长度。
输出格式:
仅一个整数:最大牧场面积乘以100然后舍尾的结果。如果无法构建,输出-1。
输入输出样例
输入样例#1:
5
1
1
3
3
4
输出样例#1:
692
说明
样例解释:692=舍尾后的(100×三角形面积),此三角形为等边三角形,边长为4。
我们把三角形的三条边当做搜索的变量。
那么当我们知道其中两个边的长度的话,就可以推出第三条边的长度。
对于每一个木棒,我们都有三种策略
1.加到第一条边
2.加到第二条边
3.加到第三条边。
然后暴力记忆化搜索就好了!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
#include<map>
#define lli long long int
using namespace std;
const int MAXN=;
void read(int &n)
{
char c='+';int x=;bool flag=;
while(c<''||c>'')
{c=getchar();if(c=='-')flag=;}
while(c>=''&&c<='')
{x=x*+(c-);c=getchar();}
flag==?n=-x:n=x;
}
int n;
int fi,se;
int vis[MAXN];
int sum=;
int a[MAXN];
int happen[MAXN];
double ans=-;
map<string,bool>mp;
double calc(double yi,double er,double san)
{
if(min(min(yi,er),min(er,san))+min(min(yi,er),min(er,san))>max(max(yi,er),max(er,san)))
{
double p=(yi+er+san)/;
return sqrt(p*(p-yi)*(p-er)*(p-san));
}
else
return -;
}
int comp(const int a,const int b)
{
return a<b;
}
void dfs(int yi,int er,int san)
{
if(happen[yi*+er*+san])
return ;
happen[yi*+er*+san]=;
if(yi+er+san==sum&&yi!=&&er!=&&san!=)
{
double hh=calc(yi,er,san);
if(hh>ans)
ans=calc(yi,er,san);
} for(int i=;i<=n;i++)
{
if(vis[i]==)
{
vis[i]=;
dfs(yi+a[i],er,sum-(yi+a[i]+er));
dfs(yi,er+a[i],sum-(yi+er+a[i]));
vis[i]=;
dfs(yi,er,sum-(yi+er));
}
}
}
int main()
{ read(n);
for(int i=;i<=n;i++)
{
read(a[i]); sum+=a[i];
}
sort(a+,a+n+,comp);// 排序是为了方便调试
dfs(,,);
if(ans==-)
{ printf("-1"); return ;}
ans=ans*100.0;
printf("%d",(int)ans);
return ;
}