题目链接:http://poj.org/problem?id=1948
题目大意:
p.s.跟原题不一样的都删掉了。。不理解的话看poj上的吧
题解:
背包..
f[i][j][k]表示取到第i根木棒,一条边的值取到了j,还有一条边的值取到了k。
转移就是:if f[i-1][j][k] {f[i][j+a[i]][k]=1; f[i][j][k+a[i]]=1;f[i][j][k]=1;}
每次判断能否构成三角形并取面积的最大值。要滚动!
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int a[50],f[2][1700][1700]; double mymax(double x,double y){return (x>y)?x:y;} double ss(double x,double y,double z)//海伦公式算面积 { double p=(x+y+z)/2; double ret=sqrt(p*(p-x)*(p-y)*(p-z))*100.0; return ret; } bool pd(int x,int y,int z)//判断能否构成三角形 { if (!(x!=0 && y!=0 && z!=0)) return false; if (z<x+y && z>abs(x-y)) return true; return false; } int main() { //freopen("pasture.in","r",stdin); //freopen("pasture.out","w",stdout); int n,i,j,k,t,sum; scanf("%d",&n); double ans;sum=0; for (i=1;i<=n;i++) { scanf("%d",&a[i]); sum+=a[i]; }t=0;ans=-1;//sort(a+1,a+1+n); memset(f,0,sizeof(f)); f[1][0][0]=1; for (i=1;i<=n;i++) { for (j=0;j<=sum/2;j++) for (k=0;k<=sum/2;k++) if (f[1-t][j][k]) { f[t][j][k]=1; f[t][j+a[i]][k]=1; f[t][j][k+a[i]]=1; if (pd(j+a[i],k,sum-k-j-a[i])) ans=mymax(ans,ss(j+a[i],k,sum-k-j-a[i])); if (pd(j,k+a[i],sum-k-j-a[i])) ans=mymax(ans,ss(j,k+a[i],sum-k-j-a[i])); }t=1-t; } printf("%d ",(int)ans); return 0; }