DP的做法比较麻烦我并不会
我选择贪心。
显然,三边的差越小,他的面积就越大
所以:每次将木板加入当前的最短边即可完成贪心
但是贪心成功的概率较小,这时可以想到使用随机化!!
前置技能
- 海伦公式:sqrt(p(p-a)(p-b)*(p-c)),其中p=(a+b+c)/2
- trunc函数来舍尾
#include<bits/stdc++.h>
#define inf 1e9
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n,a[41],ans=-1;
int read()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
return x*f;
}
void wash()//随机洗木板顺序
{
rep(i,1,n)
{
int t=rand()%n;
a[0]=a[t];
a[t]=a[i];
a[i]=a[0];
}
}
int helen(double a,double b,double c)//海伦公式求面积
{
if(a+b>c && b+c>a && a+c>b)
{
double p=(a+b+c)/2;
return trunc(sqrt(p*(p-a)*(p-b)*(p-c))*100);
}
else return -1;
}
void work()//贪心程序
{
int p[3],pos;
p[0]=a[1];
p[1]=a[2];
p[2]=a[3];
rep(i,4,n)
{
int min=0x7fffffff;
rep(j,0,2)
{
if(min>p[j])
{
min=p[j];
pos=j;
}
}
p[pos]+=a[i];
}
ans=max(ans,helen(p[0],p[1],p[2]));
}
int main()
{
n=read();
rep(i,1,n)
a[i]=read();
rep(time,1,10000)
{
wash();
work();
}
printf("%d
",ans);
return 0;
}