Triangular Pastures
二维背包。dp[j][k]表示是否组成长度为j和k的两个长度。这里可以设j>k.
dp[i][j][k]= (dp[i-1][j-a[i]][k] || dp[i-1][j][k-a[i]]) ;
我们可以省略掉一维,只要转移的时候,j和k的值从大到小枚举,就可避免改变原来的值.
这里有个很诡异的地方,我对a[]数组进行从小到大排序之后,提交到poj就会WA。
删去这个排序就可以AC。各种不懂。貌似这里根那个排序没多大的关系吧。。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
int a[50];
int dp[2000][2000];
int cmp(int x,int y)
{
return x<y;
}
int main()
{
int n;
/*freopen("test.in","r",stdin);
freopen("test1.out","w",stdout);*/
while(scanf("%d",&n)!=EOF)
{
int sum=0;
int ans=-1;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
memset(dp,0,sizeof(dp));
// sort(a+1,a+n+1,cmp);
dp[0][0]=1;
int tsum=0;
for(int i=1;i<=n;i++)
{
tsum+=a[i];
for(int j=sum;j>=0;j--)
{
for(int k=j;k>=0;k--)
{
if(j>=a[i] && dp[j-a[i]][k]==1)
dp[j][k]=1;
if(k>=a[i] && dp[j][k-a[i]]==1)
dp[j][k]=1;
}
}
}
for(int i=1;i<=sum;i++)
{
for(int j=1;j<=i;j++)
{
if(dp[i][j]==0)
continue;
int k=sum-i-j;
if(i+j>k && i+k>j && j+k>i && k>0)
{
double p=(i+j+k)/2.0;
int temp=(int)(sqrt(p*(p-i)*(p-j)*(p-k))*100);
if(temp>ans)
ans=temp;
}
}
}
if(ans==-1)
printf("-1\n");
else
printf("%d\n",ans);
}
return 0;
}