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 ", (int)(ans*100)); 48 else printf("-1 "); 49 return 0; 50 }