题目描述
给出 nnn 根长度不一的木棍,第 iii 根棍子长度为 aia_iai 。两根长度分别为 aba_bab 和 aca_cac 的木棍可以拼接成一根长度为 ab+aca_b+a_cab+ac 的木棍,同理 333 根, 444 根,甚至 nnn 根都能拼接。
问:使用这 nnn 根木棍作三角形的边(一根木棍至多使用一次,也可以不使用),能拼出的面积最大的三角形的面积。
第一行包含一个整数 nnn (3≤n≤8)(3 \le n \le 8)(3≤n≤8),表示木棍的数量。
第二行包含 nnn 个整数,用空格隔开,表示 nnn 根木棍的分别长度 a1,a2,...,ana_1,a_2,...,a_na1,a2,...,an 其中 1≤ai≤1e31\le a_i\le 1e31≤ai≤1e3。
输出一行,表示能拼出来的最大三角形的面积,结果保留一位小数。如果无法拼出三角形,输出−1-1−1。
示例1
3 3 4 5
6.0
示例2
3 3 4 7
-1
这一题似乎不太能贪心,规律并不好找,但是因为数据量很小,就采用最暴力的方法,用搜索来解决
可以看出一个木棍有四种状态,在第一条边,第二条边,第三条边,不在任何一条边,这里就把a,b,c当做三角形的第1,2,3条边,dfs搜索以下边为参数,向前走一直走到没有元素为止,这个时候判断一下三角形是否合法并更新ans就可以
有一些小细节就写在程序里了
#include<stdio.h> #include<algorithm> #include<math.h> using namespace std; int xx[1000]; int a, b, c; int n; double ans=-1; double s(int a, int b,int c) { double p = (a + b + c) / 2; return sqrt(p*(p-a)*(p-b)*(p-c)); } void dfs(int x) { if (x > n)//枚举超出了数组,代表所有的数都有了位置, { if (a < b + c && b < a + c && c < a + b)//满足条件 { //printf("%d %d %d\n",a,b,c); ans = max(ans, s(a, b, c)); return; } else return; } //接下来搜索四种状态-->a[x]不放,放第一二三条边, ;//直接跳过这个数 dfs(x + 1); a +=xx[x];//第一条边 dfs(x + 1); a -= xx[x]; b += xx[x];//放第二条边 dfs(x + 1); b -= xx[x]; c += xx[x];//第三跳 dfs(x + 1); c-=xx[x];//最后一步取出来的操作不能忘记 } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", xx + i); dfs(1); if (ans == -1)printf("-1\n"); else printf("%.1lf\n", ans); return 0; }