题目链接:link
题目大意:
给出 n 根长度不一的木棍,第 i 根棍子长度为
a
i
a_i
ai 。两根长度分别为
a
b
和
a
c
a_b 和 a_c
ab和ac的木棍可以拼接成一根长度为
a
b
+
a
c
a_b+a_c
ab+ac 的木棍,同理 3 根,4 根,甚至 n 根都能拼接。
问:使用这 n 根木棍作三角形的边(一根木棍至多使用一次,也可以不使用),能拼出的面积最大的三角形的面积。
解题思路:
通过数据范围可知 n 最大为 8 ,所以我们可以用二进制枚举来枚举每一条边是由那些木棍组成。复杂度O ( ( 1 < < n ) 3 ) ((1<<n)^3) ((1<<n)3)。
AC代码:
#include <bits/stdc++.h>
using namespace std;
int a[10], n;
double cal(int x) //将选中的木棍长度加起来
{
double ans = 0;
for (int i = 0; i < n; i++)
{
if (x >> i & 1) ans += a[i];
}
return ans;
}
bool check(double a, double b, double c) //判断a,b,c三条边是否能够组成三角形
{
if (a > b) swap(a, b);
if (a > c) swap(a, c);
if (b > a) swap(b, c);
return a + b > c;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
double ans = -1;
for (int i = 0; i < (1 << n); i++) //枚举第一条边
{
double A = cal(i);
for (int j = 0; j < (1 << n); j++) //枚举第二条边
{
if (i & j) continue; //判断是否重复选用木棍
double B = cal(j);
for (int k = 0; k < (1 << n); k++) //枚举第三条边
{
if (i & k || j & k) continue; //判断是否重复选用木棍
double C = cal(k);
if (check(A, B, C))
{
double p = (A + B + C) / 2;
ans = max(ans, sqrt(p * (p - A) * (p - B) * (p - C)));
}
}
}
}
if (ans < 0) puts("-1");
else printf("%.1f\n", ans);
return 0;
}