1 条题解

  • 0
    @ 2025-4-12 23:02:12

    分析: 1 题目要求从n个木棒里面选出m个组成一个三角形,使得三角形的面积最大 2 对于三角形来说知道了两条边和周长就可以求面积,按照0/1背包的思想dp[i][j][k]表示前i个木棒能否组成第一条边为长度j,第二条长度为k。如果dp[j-v[i]][k] 或dp[j][k-v[i]] 为true则dp[j][k]就为true 3 我们求出了所有可能的组合之和,就去枚举所有的边长的情况,然后求最大的面积

    
    
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int f[2010][2010],n,a[2010],sum,m;
    double ans;
    inline int abss(int x)
    {
    	if(x>=0) return x;
    	return -x;
    }
    inline bool check(int a,int b,int c)
    {
    	if(a+b>c&&c>abss(a-b)&&a+c>b&&b>abss(a-c)&&b+c>a&&a>abss(b-c)) return 1;
    	return 0;
    }
    int main()
    {
    	int i,j,k;
    	scanf("%d",&n);
    	for(i=1;i<=n;++i) scanf("%d",&a[i]),sum+=a[i];
    	m=sum;
    	f[0][0]=1;
    	for(i=1;i<=n;++i)
    	 for(j=m;j>=0;--j)//m从最大值开始枚举才能保证包含所有的情况,我刚开始为了保证两边之和大于第三边,从一半开始枚举,然后WA、WA、WA! 
    	  for(k=m;k>=0;--k)
    	   {
                if (j-a[i]>=0) f[j][k]|=f[j-a[i]][k];
                if (k-a[i]>=0) f[j][k]|=f[j][k-a[i]];
            }//这个地方明白为什么写成  if(j-a[i]>=0&&f[j-a[i]][k]||k-a[i]>=0&&f[j][k-a[i]])  f[i][j]=1;  就会错。。。 
    	for(i=m;i>0;--i)
    	 for(j=m;j>0;--j)
    	  if(f[i][j])
    	   {
    	   	int c=sum-i-j;
    	   	if(!check(i,j,c)) continue;
    	   	double p=(double)sum/2.0;
    	   	double S=sqrt(p*(p-i)*(p-j)*(p-c));
    	   	ans=max(ans,S);
    	   }
    	if(ans==0) printf("-1\n");
    	 else printf("%.0lf\n",floor(ans*100));
    	return 0;
    }
    
    • 1

    信息

    ID
    949
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者