1 条题解
-
0
分析: 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
- 上传者