背包问题POJ 1948 Triangular Pastures[二维01背包]

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

算法核心:二维01背包
  使用到海伦公式:
  已知三角形的三边长度a,b,c,求面积
   S=√[p(p-a)(p-b)(p-c)]
  而公式里的p为半周长:
  p=(a+b+c)/2

分析:用dp[i][j][k]表示到第i根木棒能否摆出边长分别为j,k的三角形
     易得 dp[i][j][k] = dp[i-1][j-x[i]][k]|dp[i-1][j][k-x[i]]|dp[i-1][j][k];
  简单的空间压缩,化为二维dp,注意:这里每根木棒只能使用一次,
  是01背包,要倒着扫(刚开始错在这里了。。。)

#include<stdio.h>
#include
<string.h>
#include
<math.h>
constint N =801;
bool dp[N][N];//dp[i][j]表示取两边分别为i,j可达
int x[N];
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i,j,k;
int sum =0;
for(i=0;i<n;i++)
{
scanf(
"%d",&x[i]);
sum
+=x[i];
}

memset(dp,
false,sizeof(dp));
dp[
0][0]=true;
int half = sum>>1;
for(i=0;i<n;i++)
for(j=half;j>=0;j--)
for(k=j;k>=0;k--)
{
if(x[i]<=j)
dp[j][k]
|=dp[j-x[i]][k];
if(k>=x[i])
dp[j][k]
|=dp[j][k-x[i]];
}
double ha = sum/2.0;
double ans =-1;
for(i=0;i<half;i++)
for(j=0;j<=i;j++)
{
if(dp[i][j])
{
k
=sum-i-j;
if(i+j>k&&i+k>j&&k+j>i)
{
double temp = ha*(ha-i)*(ha-j)*(ha-k);
if(temp>ans)ans=temp;
}
}
}

intout;
if(ans<0)out=-1;
else
out= (int)(sqrt(ans)*100);

printf(
"%d\n",out);
}
return0;
}
原文地址:https://www.cnblogs.com/AndreMouche/p/1951696.html