这题WA了很多遍,要不就是测试数据 3 1 2 3 输出173,要不就是6 5 5 5 5 5 5 输出-1.甚至有时候把程序改的题目上的测试数据都过不了,各种悲摧,其实我喜欢边写程序边想,这是个很差的习惯,我一定要改!!!这题是看别人的提示写出来的,首先设bool型数组f,令 f[i][j]表示一边长为i,另一边长为j的边可以组合出来,然后在所有可以组合出来的情形中找能组合成三角形且面积最大的。f[i][j]能组合出来的条件是对于加入新边li来说是f[i-li][j] 或f[i][j-li]能组合出来,初始条件是f[0][0]能组合出来。因为题目中说了要用掉所有的栏杆,所以我只考虑两条边,剩下的一条边用总长剪这两条边的长就知道了,然后为了这两天边的列举有对称性,可假设i>= j也算是减少运算量吧。能组成三角形的条件是任意两边之和大于第三边,我令第一条边长i <= (总长-1)/2(稍微想一下就知道了,分奇偶讨论一下)第二条边长<= i且和 i一起满足2*(i+j) > 总长,这样的三条边就一定是能组成三角形的了``````
View Code
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 bool f[900][900]; 5 int main() 6 { 7 int n,l[50]; 8 int sum =0; 9 scanf("%d",&n); 10 for(int i=0; i< n; i++) 11 { 12 scanf("%d",&l[i]); 13 sum += l[i]; 14 } 15 int m1; 16 m1=(sum-1)/2; 17 memset(f,false,sizeof(f)); 18 f[0][0] = true; 19 for(int i=0; i< n; i++) 20 { 21 for(int j = m1; j >= 0; j--) 22 { 23 for(int k = j; k>=0; k--) 24 { 25 if((j>=l[i] &&f[j-l[i]][k]) || (k >= l[i] && f[j][k - l[i]])) 26 f[j][k] = true; 27 } 28 } 29 } 30 double max = 0; 31 bool flag= false; 32 for(int j=m1; j>0; j--) 33 { 34 for(int k = j; 2*(j+k) > sum; k--) 35 { 36 double t=(sum-2*j)*(sum-2*k)*(2*(j+k)-sum)/8.0; 37 if(f[j][k] && t> max) 38 { 39 flag =true; 40 max = t; 41 } 42 } 43 } 44 if(!flag) 45 printf("-1\n"); 46 else 47 { 48 max = sum/2.0*max; 49 int d = (floor)(sqrt(max)*100); 50 printf("%d\n",d); 51 } 52 return 0; 53 }