Triangular Pastures
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 6124 | Accepted: 1978 |
Description
Like everyone, cows enjoy variety. Their current fancy is new shapes for pastures. The old rectangular shapes are out of favor; new geometries are the favorite.
I. M. Hei, the lead cow pasture architect, is in charge of creating a triangular pasture surrounded by nice white fence rails. She is supplied with N (3 <= N <= 40) fence segments (each of integer length Li (1 <= Li <= 40) and must arrange them into a triangular pasture with the largest grazing area. Ms. Hei must use all the rails to create three sides of non-zero length.
Help Ms. Hei convince the rest of the herd that plenty of grazing land will be available.Calculate the largest area that may be enclosed with a supplied set of fence segments.
I. M. Hei, the lead cow pasture architect, is in charge of creating a triangular pasture surrounded by nice white fence rails. She is supplied with N (3 <= N <= 40) fence segments (each of integer length Li (1 <= Li <= 40) and must arrange them into a triangular pasture with the largest grazing area. Ms. Hei must use all the rails to create three sides of non-zero length.
Help Ms. Hei convince the rest of the herd that plenty of grazing land will be available.Calculate the largest area that may be enclosed with a supplied set of fence segments.
Input
* Line 1: A single integer N
* Lines 2..N+1: N lines, each with a single integer representing one fence segment's length. The lengths are not necessarily unique.
* Lines 2..N+1: N lines, each with a single integer representing one fence segment's length. The lengths are not necessarily unique.
Output
A single line with the integer that is the truncated integer representation of the largest possible enclosed area multiplied by 100. Output -1 if no triangle of positive area may be constructed.
Sample Input
5 1 1 3 3 4
Sample Output
692
题目意思:给出栅栏的总条数N和每条栅栏的长度,用上所有的栅栏拼接成一个三角形,求所有能拼接成功的三角形中面积最大的那个,只要求输出最大的面积乘上100的值(最后的答案要求为整数)。
解题思路:1.首先使用二维01背包枚举出所有能够由目前仅有的栅栏构成的两条长度分别为j,k的边; 2.因为所有栅栏的总长度为sum,则第三条边为c = sum-j-k,判断由j, k, c三条边是否能够构成三角形; 3.计算出所有三角形的面积,从中求出最大的那个,最后用最大的面积乘上100。
注意:1.三角形的每条边的长度必须小于三角形周长的一半,所以这个地方需要用到一个剪枝( j<(sum>>1) ); 2.为了避免重复计算,要求( k <= j ); 3.dp[][]数组的大小至少为L_max*N / 2;(dp[j][k]表示是否能够由已有的栅栏得到两条长度分别为j,k的边;而由已有栅栏所能得到的最长的边为L_max*N;但是每条边的长度要小于周长的一半,于是数组大小至少为dp[L_max*N / 2][L_max*N / 2])
#include<iostream> #include<string.h> #include<math.h> using namespace std; int X[42]; bool dp[802][802]; int main() { int N; while(cin>>N){ int sum = 0; for(int i = 0; i < N; i++){ cin>>X[i];//首先输入所有栅栏的长度 sum += X[i]; } int half = sum >> 1; memset(dp, false, sizeof(dp));//假设无法得到两条长度分别为j,k的边 dp[0][0] = true; for(int i = 0; i < N; i++){ for(int j = half; j >= 0; j--){ for(int k = j; k >= 0; k--){ if(X[i] <= j) dp[j][k] = dp[j][k] | dp[j-X[i]][k]; if(X[i] <= k) dp[j][k] = dp[j][k] | dp[j][k-X[i]]; } } } double ans = -1; for(int j = half; j >= 0; j--){ for(int k = j; k >= 0; k--){ if(dp[j][k]){//首先判断是不是可以构成长度为j,k的两条边 int c = sum - j - k; if(j+k > c && j+c > k && k+c > j){//如果j, k, c可以构成三角形 double ha = sum/2.0; double temp = ha*(ha-c)*(ha-j)*(ha-k);//算出该三角形的面积 if(temp>ans)ans=temp; //对面积进行优化处理 } } } }//for int out; if(ans < 0) out = -1; else out = int (sqrt(ans) * 100); cout<<out<<endl; }//while() return 0; }