POJ 1948 Triangular Pastures

USACO 2002 February 的一道题

题意是,把很多单独的线段重新组合成一个三角形,使得三角形面积最大。所有的线段都必须用上。

解法是动态规划。

用背包的思路,dp[i][j]为1,表示从这些线段中可以组成一个边长为i,另一边为j的三角形;为0则表示不能。

因为周长是一定的,所以dp[i][j]表示一个三角形的边分别是i,j,c-i-j,通过海伦公式就能算出面积。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
bool check[1000][1000];
double check_and_calc_the_area(int a,int b,int c,double &t)
{
    double q;
    if (a+b <= c || a+c <= b || b+c <= a)
        return false;
    q=(a+b+c)/2.0;
    t=sqrt(q*(q-a)*(q-b)*(q-c));
    t*=100;
    return true;
}
int main()
{
    int hc,i,j,k,c,l[50],n,ans;
    double t;
    scanf("%d",&n);
    c=0;
    for (i=0; i<n; i++)
    {
        scanf("%d",l+i);
        c+=l[i];
    }
    hc=c>>1;
    memset(check,false,sizeof(check));
    check[0][0]=true;
    for (i=0; i<n; i++)
    {
        for (j=hc; j>=0; j--)
        {
            for (k=hc; k>=0; k--)
            {
                if (j >= l[i])
                {
                    if (check[j-l[i]][k])
                        check[j][k]=true;
                }
                if (k >= l[i])
                {
                    if (check[j][k-l[i]])
                        check[j][k]=true;
                }
            }
        }
    }
    ans=0;
    for (i=1; i<=hc; i++)
    {
        for (j=1; j<=hc; j++)
        {
            if (check[i][j] == true)
            {
                if (check_and_calc_the_area(i,j,c-i-j,t) == true)
                    ans=(int)t>ans?(int)t:ans;
            }
        }
    }
    printf("%d",ans==0?-1:ans);
}


你可能感兴趣的:(POJ 1948 Triangular Pastures)