Poj--1948(DP)

2014-12-11 13:26:24

思路:用dp[i][j]来表示当一条边长度为i时,另一条边为j是否能成立。

  由于周长最多为1600,所以每条边 < 800,因为dp[i][j] = dp[j][i],不妨令i > j 来提升效率。然后就是可行性DP了。

 1 /*************************************************************************
 2     > File Name: 1948.cpp
 3     > Author: Natureal
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Wed 10 Dec 2014 04:24:34 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <vector>
13 #include <map>
14 #include <set>
15 #include <stack>
16 #include <queue>
17 #include <iostream>
18 #include <algorithm>
19 using namespace std;
20 #define lp (p << 1)
21 #define rp (p << 1|1)
22 #define getmid(l,r) (l + (r - l) / 2)
23 #define MP(a,b) make_pair(a,b)
24 typedef long long ll;
25 const int INF = 1 << 30;
26 
27 int N,L[50];
28 int dp[810][810];
29 int sum;
30 
31 int main(){
32     scanf("%d",&N);
33     for(int i = 1; i <= N; ++i){
34         scanf("%d",L + i);
35         sum += L[i];
36     }
37     memset(dp,0,sizeof(dp));
38     dp[0][0] = 1;
39     int ans = 0;
40     for(int k = 1; k <= N; ++k){
41         for(int i = sum / 2; i >= 0; --i){
42             for(int j = i; j >= 0; --j){
43                 if((i >= L[k] && dp[i - L[k]][j]) || (j >= L[k] && dp[i][j - L[k]])){
44                     dp[i][j] = 1;
45                 }
46             }
47         }
48     }
49     int bot = sum / 3;
50     double p = sum / 2.0;
51     for(int i = sum / 2; i > 0; --i){
52         for(int j = i; j > 0; --j){
53             if(dp[i][j] == 0) continue;
54             int o = sum - i - j;
55             ans = max(ans,(int)(sqrt(p * (p - i) * (p - j) * (p - o)) * 100));
56         }
57     }
58     if(ans == 0) printf("-1\n");
59     else printf("%d\n",ans);
60     return 0;
61 }

 

posted @ 2014-12-11 13:27  Naturain  阅读(128)  评论(0编辑  收藏  举报