您的位置:首页 > 其它

poj1948 二维背包

2014-04-12 11:42 190 查看
携程的第二场第二题,比赛时被水过去了。。。

题目给一些木棒,要求全部用上形成三条边,问能形成的三角形最大面积是多少?

题意很明确,只需要确定所有能形成的边的组合,再从这些组合中求最大值即可。

用二维数组dp[i][t]表示边长分别为i和t,两边确定,第三条边边长为sum-i-t,然后就是背包确定能否形成i和t两条边的过程了。

很简单的二维背包,比赛时看出来是背包,没想到这点,以至于花了大把时间去水掉,还是做过的题目太少。

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

int dp[801][801];
int a[41];
int n;
double sum;

bool sap(int a,int b,int c)
{
    if (a+b>c&&a+c>b&&b+c>a)
        return true;
    return false;
}

int s(int a,int b,int c)
{
    double ss=sum/2;
    ss=ss*(ss-a)*(ss-b)*(ss-c);
    ss=sqrt(ss)*100;
    int t=ss;
    return t;
}

int main()
{
    while (~scanf("%d",&n))
    {
        sum=0;
        for (int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
        }
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for (int i=0;i<n;i++)
        {
            for (int t=sum/2;t>=0;t--)
            {
                for (int k=sum/2;k>=0;k--)
                {
                    if ((t>=a[i]&&dp[t-a[i]][k])||(k>=a[i]&&dp[t][k-a[i]]))
                        dp[t][k]=1;
                }
            }
        }
        int m=-1;
        for (int i=0;i<=sum/2;i++)
        {
            for (int t=0;t<=sum/2;t++)
            {
                if (dp[i][t]&&sap(i,t,sum-i-t))
                {
                    int cur=s(i,t,sum-i-t);
                    m=m>cur?m:cur;
                }
            }
        }
        printf("%d\n",m);
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: