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 }