The main effect of the topic:
To the n edge, to make these edges into a triangle, ask what is the largest area? All sides must be used.
Ideas:
For triangles with known perimeter, we can get the equation of state by knowing that the length of the two edges can be used to eject the third edge:
F[I][J][K] Represents the use of the front I edge, can be composed of a length of J and K two edges
Initialize f[0][0][0] = true;
F[I][J][K] = F[i-1][j-len[i]][k] | | F[i-1][j][k-len[i]];
If f[i][j][k]=true, then calculate whether j,k,sum-j-k three edges can form a triangle, and if so, use Helen's formula to calculate the area.
Because if you want to open a three-dimensional array, to open f[40][1600][1600], obviously to be mle, so to be reduced to two-dimensional,
and time complexity 40*1600*1600, if not optimized directly, is to tle.
So to optimize, according to the degree of optimization, the running time can be 100ms~1000ms between:
1. F[i][j] and F[j][i] are the same two triangles, so recursion allows the j>=i
2. For each side, it must be less than half the perimeter.
3. When enumerating to the edge of article I, the length of the front I sidebar cannot consist of greater than or equal to Sum[i] (Sum[i]=len[1]+...+len[i])
Optimized for a while to 100ms+
Code:
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <
cstring> #include <vector> #define SQ (x) ((x) * (x)) #define MP Make_pair const int INF = 0X3F3F3F3F;
Const double PI = ACOs (-1.0);
typedef long long Int64;
using namespace Std;
const int MAXN = 42;
int n, m;
int LEN[MAXN], SUM[MAXN];
BOOL f[1602][1602];
inline bool Istriangle (double e[3]) {if (e[2] < e[1]) {swap (e[2), e[1]);
if (E[1] < e[0]) swap (e[0], e[1]);
return e[0]+e[1] > e[2];
Inline double Getarea (double e[3]) {if (!istriangle (e)) return-1;
Double p = sum[n]/2.0;
return sqrt (p* (p-e[0)) * (p-e[1)) * (p-e[2));
int main () {scanf ("%d", &n);
for (int i=1; i<=n; ++i) {scanf ("%d", &len[i]);
Sum[i] = Sum[i-1]+len[i];
} memset (f, 0, sizeof (f));
F[0][0] = true; Double ans =-1;
Double e[3]; for (int i=1; i<=n; ++i) {for (int v1=min (sum[i],sum[n]>>1); v1>=0;--v1) {for (int v2=mi N (sum[i]-v1,sum[n]>>1); v2>=v1;
--V2) if (V1+v2<sum[n]) {e[0] = v1; e[1] =v2; e[2] = Sum[n]-v1-v2;
if (v1-len[i]>= 0 && f[v1-len[i]][v2]) {F[v1][v2] = true; } if (!f[v1][v2] && v2-len[i]>=0 && F[v1][v2-len[i]]) {F[V1][V2]
= true;
} if (F[v1][v2]) {ans = max (ans, Getarea (e));
}} if (Ans < 0) puts ("-1");
else printf ("%d\n", (int) (100*ans));
return 0; }
See more highlights of this column: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/sjjg/