POJ1948http://poj.org/problem?id=1948
题目大意就是说给你n个木棍让你用它们摆成一个三角形 使得这个三角形的面积最大。
这个题我之前想的时候一直纠结怎么通过之前的三角形面积推导出加上一条木棍后的面积,结果一直没有想明白,而且总周长达到了1600,他的平方肯定会超时才对。后来看了网上的题解才明白其实DP求出来的并不是这些三角行是面积,而是求出通过这n个木棍可以构成哪些边长组合的三角形,最后再一一比较这些三角形的面积。
至于判断三角形,由于最长的边也不可能超过三角形周长的一半,也就是800,所以最后的结果就是800*800自然不会超时。
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <cmath> 6 #include <ctime> 7 #include <vector> 8 #include <cstdio> 9 #include <cctype> 10 #include <cstring> 11 #include <cstdlib> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 #define INF 0x3f3f3f3f 16 #define MAX(a,b) (a > b ? a : b) 17 #define MIN(a,b) (a < b ? a : b) 18 #define mem0(a) memset(a,0,sizeof(a)) 19 20 typedef long long LL; 21 const double eps = 1e-12; 22 const int MAXN = 1005; 23 const int MAXM = 5005; 24 25 bool DP[880][880]; 26 int len[42], tot, N; 27 28 bool Judge(int a,int b,int c) 29 { 30 if(a+b>c && a+c>b && b+c>a) return true; 31 return false; 32 } 33 34 double area(int a, int b, int c) 35 { 36 double p = (double)(a+b+c)/2.0; 37 return sqrt(p*(p-a)*(p-b)*(p-c)); 38 } 39 40 int main() 41 { 42 while(~scanf("%d", &N)) 43 { 44 tot = 0; mem0(DP); 45 for(int i=0;i<N;i++) 46 { 47 scanf("%d", &len[i]); 48 tot += len[i]; 49 } 50 int half = tot/2; 51 DP[0][0] = 1; 52 for(int i=0;i<N;i++) 53 { 54 for(int j=half;j>=0;j--) 55 { 56 for(int k=half;k>=0;k--) 57 { 58 if((j>=len[i]&&DP[j-len[i]][k]) || (k>=len[i]&&DP[j][k-len[i]])) 59 { 60 DP[j][k] = 1; 61 } 62 } 63 } 64 } 65 double ans = -1; 66 for(int i=0;i<=half;i++) 67 { 68 for(int j=0;j<=half;j++) 69 { 70 if(DP[i][j] && Judge(i,j,tot-i-j)) 71 { 72 ans = max(ans, 100*area(i,j,tot-i-j)); 73 } 74 } 75 } 76 printf("%d ", (int)ans); 77 } 78 return 0; 79 }