1948

/*
p = (a+b+c)/2;
S^2 = p*(p-a)*(p-b)*(p-c)

这些包可以形成所有的可行边长
DP问题。

二维的DP背包问题,对于二维的01背包的理解,可以从一维的开始理解
一维01背包的方程是 DP[k] = max(DP[k],DP[k-代价]+价值);,这里DP方程意思是说,代价为K时的最大价值
二维01背包的方程是 DP[k1][k2] = max(DP[k1][k2],DP[k1-代价][k2]+价值,DP[k1][k2-代价]+价值);,这里DP方程是说,代价为k1和k2时的最大价值
当然对于多维,DP在加一位就是了。
这里唯一区别的地方是,每个物品只能在一个背包中,所以如果在1中用了,就不能在2中,如果在2中用了,就不用在其他的里面,等等
这样理解起来貌似更好记,对于N维道理是一样的


*/

// include file
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <ctime>

#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <bitset>

#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <list>
#include <functional>

using namespace std;

// typedef
typedef __int64 LL;

// 
#define read freopen("in.txt","r",stdin)
#define write freopen("out.txt","w",stdout)

#define Z(a,b) ((a)<<(b))
#define Y(a,b) ((a)>>(b))

const double eps = 1e-6;
const double INFf = 1e100;
const int INFi = 1000000000;
const LL INFll = (LL)1<<62;
const double Pi = acos(-1.0);

template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T TMAX(T x,T y)
{
	if(x>y) return x;
	return y;
}
template<class T> inline T TMIN(T x,T y)
{
	if(x<y) return x;
	return y;
}
template<class T> inline T MMAX(T x,T y,T z)
{
	return TMAX(TMAX(x,y),z);
}
template<class T> inline T MMIN(T x,T y,T z)
{
	return TMIN(TMIN(x,y),z);
}
template<class T> inline void SWAP(T &x,T &y)
{
	T t = x;
	x = y;
	y = t;
}


// code begin
int N;
int data[45];
bool DP[810][810]; //一条边为i,一条边为j的三角形
int main()
{
	read;
	write;
	int up,sum;
	while(scanf("%d",&N)==1)
	{
		up = 0;
		for(int i=0;i<N;i++)
		{
			scanf("%d",data+i);
			up += data[i];
		}
		sum = up;
		up /= 2;
		memset(DP,0,sizeof(DP));
		DP[0][0] = 1;
		for(int i=0;i<N;i++)
		{
			for(int j=up;j>=0;j--)
			{
				for(int k=up;k>=0;k--)
				{
					DP[j][k] |= ((k-data[i]>=0)?DP[j][k-data[i]]:0) | ((j-data[i]>=0)?DP[j-data[i]][k]:0);
				}
			}
		}
		double a,b,c,p,area,ans=-1.0;
		for(int j=up;j>=0;j--)
		{
			for(int k=up;k>=0;k--)
			{
				if(DP[j][k])
				{
					a = j;
					b = k;
					c = sum+0.0-a-b;
					if( a+b<c || a+c<b || b+c<a) continue;
					p = (a+b+c)/2;
					area = sqrt(p*(p-a)*(p-b)*(p-c));
					if(area>ans)
						ans=area;
				}
			}
		}
		if(ans==-1.0) printf("-1\n");
		else printf("%d\n",(int)(ans*100));
	}
	return 0;
}

posted @ 2011-04-20 17:23  AC2012  阅读(737)  评论(0编辑  收藏  举报