雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

二维背包——poj1948

Posted on 2011-12-05 21:22  huhuuu  阅读(273)  评论(0编辑  收藏  举报

http://poj.org/problem?id=1948

题目描述:给最多40根木棍,每根长度不超过40,要用完所有的木棍构成面积最大的三角形,求出最大的面积。

f[j][k] 表示能否达到一边长为 j,另一边长为k

if(j>=a[i])

f[j][k]=f[j][k]||f[j-a[i]][k]

if(k>=a[i])

f[j][k]=f[j][k]||f[j][k-a[i]]

View Code
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;

bool f[809][809];
int a[49];

int san(int a,int b,int c)
{
if(a>b)swap(a,b);
if(a>c)swap(a,c);
if(b>c)swap(b,c);

if(a+b<c)return -1;
double p=(a+b+c)*1.0/2;
double ret;
ret=sqrt(p*(p-a)*(p-b)*(p-c))*100;

return (int)ret;
}

int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i,j,k,all=0,ban;
for(i=1;i<=800;i++)
{
for(j=0;i<=800;i++)
{
f[i][j]=0;
}
}


f[0][0]=1;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
all+=a[i];
}
ban=all/2;

for(i=1;i<=n;i++)
{
for(j=ban;j>=0;j--)
{
for(k=ban;k>=0;k--)
{
if(j>=a[i])
f[j][k]=f[j][k]||f[j-a[i]][k];
if(k>=a[i])
f[j][k]=f[j][k]||f[j][k-a[i]];
}
}
}

int max=-1,t;
for(i=1;i<=ban;i++)
{
for(j=1;j<=ban;j++)
{
if(f[i][j]==0)continue;

t=san(all-i-j,i,j);
if(t>max)
max=t;
}
}

printf("%d\n",max);
}
}