您的位置:首页 > 其它

poj1948 二维01背包

2018-02-07 16:35 441 查看
题目给一些木棒,要求全部用上形成三条边,问能形成的三角形最大面积是多少?
一般的做法是只管一个,这次我们是管两个。

dp[i][j],表示第一条边为i,第二条边为j的情况是否存在。不需要计算第三条边,因为第三条边就是sum-i-j。

对于当前的一根木棒,

我们按照正常的01背包做法

for(int i=0;i<n;i++)//每一个木棒

for(int j=sum/2;j>=0;j--) //第一个木棒。为什么是sum/2,因为三角形最长边不会大于sum/2的

for(int k=j;k>=0;k--) //第二个木棒

{  

    if(j>a[i]&&dp[j-a[i]][k]) //如果当前第一个木棒(背包)大于当前物体,也就是可以放进入,并且没放进之前的状态也存在

        dp[j][k]=1;

 

   if(k>a[i]&&dp[j][k-a[i]])

        dp[j][k]=1;

}

之后for遍历所有的dp,求符合条件的三角形的面积即可

#include<iostream>

#include<cstdio>

#include<cstring>

#include<queue>

#include<algorithm>

#include <fstream>

#include<vector>

#include<math.h>

using namespace std;

int dp[1000][1000];

int a[1100];

int main()

{

    int n;

    while(scanf("%d",&n)!=EOF)

    {

        int sum=0;

        for(int i=0;i<n;i++)

        {

            cin>>a[i];

            sum+=a[i];

        }

        memset(dp,0,sizeof(dp));

        dp[0][0]=1;

        for(int i=0;i<n;i++)

        {

            for(int j=sum/2;j>=0;j--)//第一根木棍

            {

                for(int k=j;k>=0;k--)//第二根木棍

                {

                    if(j>=a[i]&&dp[j-a[i]][k]||k>=a[i]&&dp[j][k-a[i]])

                    {

                       dp[j][k]=1;

                    }

                }

            }

        }

        int ans=-1;

        for(int i=sum/2;i>=1;i--)

        {

            for(int j=i;j>=1;j--)

            {

                if(dp[i][j])

                {

                    int k=sum-i-j;

                     if(i+j>k&&i+k>j&&j+k>i)

                    {

                        double p = (i + j + k) * 1.0 / 2;

                        int temp = (int)(sqrt(p * (p - i) * (p - j) * (p - k)) * 100);

                        if (temp > ans)

                            ans = temp;

                    }

                }

            }

        }

        cout<<ans<<endl;

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: