[Luogu 1284]三角形牧场

Description

和所有人一样,奶牛喜欢变化。它们正在设想新造型的牧场。奶牛建筑师Hei想建造围有漂亮白色栅栏的三角形牧场。她拥有N(3≤N≤40)块木板,每块的长度Li(1≤Li≤40)都是整数,她想用所有的木板围成一个三角形使得牧场面积最大。

请帮助Hei小姐构造这样的牧场,并计算出这个最大牧场的面积。

Input

第1行:一个整数N

第2..N+1行:每行包含一个整数,即是木板长度。

Output

仅一个整数:最大牧场面积乘以100然后舍尾的结果。如果无法构建,输出-1。

Sample Input

5
1
1
3
3
4

Sample Output

692

Hint

样例解释:692=舍尾后的(100×三角形面积),此三角形为等边三角形,边长为4。

题解

我们令$f[i][j]$表示三角形一条边长为$i$,另一条为$j$,方案是否可行。

$f$为$boolean$数组,由背包的思想,我们可以知道

$$f[i][j]|=f[i-len][j],f[i][j]|=f[i][j-len]$$

$len$为当前枚举的边的长度。

若可行,我们可以去更新一下答案。

 1 #include <set>
 2 #include <map>
 3 #include <ctime>
 4 #include <cmath>
 5 #include <queue>
 6 #include <stack>
 7 #include <vector>
 8 #include <cstdio>
 9 #include <string>
10 #include <cstring>
11 #include <cstdlib>
12 #include <iostream>
13 #include <algorithm>
14 #define LL long long
15 #define Max(a, b) ((a) > (b) ? (a) : (b))
16 #define Min(a, b) ((a) < (b) ? (a) : (b))
17 using namespace std;
18 const int INF = ~0u>>1;
19 
20 bool f[1605][1605];
21 int n, a[45], sum;
22 double ans = 0;
23 
24 void Count(double a, double b, double c){
25     if (a <= 0 || b <= 0 || c <= 0) return;
26     if (a+b <= c) return;
27     if (a+c <= b) return;
28     if (b+c <= a) return;
29     double p = (a+b+c)/2;
30     double tmp = sqrt(p*(p-a)*(p-b)*(p-c));
31     ans = max(ans, tmp);
32 }
33 
34 int main(){
35     scanf("%d", &n);
36     for (int i = 1; i <= n; i++)
37     scanf("%d", &a[i]),
38     sum += a[i];
39     f[0][0] = 1;
40     for (int k = 1; k <= n; k++)
41     for (int i = sum; i >= 0; i--)
42         for (int j = sum; j >= 0; j--){
43           if (i >= a[k]) f[i][j] |= f[i-a[k]][j];
44           if (j >= a[k]) f[i][j] |= f[i][j-a[k]];
45           if (f[i][j]) Count(i, j, sum-i-j);
46         }
47     if (ans != 0) printf("%d\n", (int)(ans*100));
48     else printf("-1\n");
49     return 0;
50 }

 

posted @ 2017-09-02 20:33  NaVi_Awson  阅读(304)  评论(0编辑  收藏  举报