第4 题 三角形牧场(pasture.pas/cpp)
【问题描述】
和所有人一样,奶牛喜欢变化。它们正在设想新造型的牧场。奶牛建筑师Hei想建造围有漂亮白色栅栏的三角形牧场。她拥有N(3≤N≤40)块木板,每块的长度Li(1≤Li≤40)都是整数,她想用所有的木板围成一个三角形使得牧场面积最大。
请帮助Hei小姐构造这样的牧场,并计算出这个最大牧场的面积。
【输入】
第1行:一个整数N
第2..N+1行:每行包含一个整数,即是木板长度。
【输出】
仅一个整数:最大牧场面积乘以100然后舍尾的结果。如果无法构建,输出-1。
【样例】
pasture.in pasture.out
5 692
1
1
3
3
4
【样例解释】
692=舍尾后的(100×三角形面积),此三角形为等边三角形,边长为4。
这个看到范围比较小,就搜了,结果TLE40。。
搜索慢的原因是,不同的木板可能会组合成相同的长度,所以重复了很多计算。
用动规预处理出木板可能的组合情况(这是01背包,一开始打成完全背包了)
然后再枚举组合,判断能否构成三角形,以及面积(海伦公式)是否更优。
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#define max(a,b) ((a)>(b)?(a):(b))
bool f[2000][2000];
long len[100];
long sum;
long n;
long getint()
{
long rs=0;
bool sgn=1;
char tmp;
do tmp=getchar();
while (!isdigit(tmp)&&tmp-'-');
if (tmp=='-'){tmp=getchar();sgn=0;}
do rs=(rs<<3)+(rs<<1)+tmp-'0';
while (isdigit(tmp=getchar()));
return sgn?rs:-rs;
}
int main()
{
freopen("pasture.in","r",stdin);
freopen("pasture.out","w",stdout);
n = getint();
for (long i=1;i<n+1;i++)
{
len[i] = getint();
sum += len[i];
}
f[0][0] = true;
for (long i=1;i<n+1;i++)
{
for (long j=sum;j>-1;j--)
{
for (long k=sum;k>-1;k--)
{
if (j-len[i] >= 0)
f[j][k] |= f[j-len[i]][k];
if (k-len[i] >= 0)
f[j][k] |= f[j][k-len[i]];
}
}
}
long ans = -1;
for (long a=0;a<sum+1;a++)
{
for (long b=a;b<sum+1;b++)
{
if (f[a][b])
{
long c = sum-a-b;
if (a+b<=c||a-b>=c||a+c<=b)
break;
double p = (a+b+c)/2.0;
long s = long(sqrt(p*(p-a)*(p-b)*(p-c))*100);
ans = max(ans,s);
}
}
}
printf("%ld",ans);
return 0;
}