poj 1948二维01背包
题意:给出不多于40个小棍的长度,求出用所有小棍组成的三角形的最大面积。
思路:三角形3边求面积,海伦公式:p=(a+b+c)/2;S=p*(p-a)*(p-b)*(p-c);因为最大周长为1600 则三角形的边长小于周长一半800;
则可以用背包思想dp[i][j]代表能组成的两条边i和j。dp为true代表小棍能组成这两条边,第三条边也能求出,最后遍历一次dp数组求最大面积。
代码:
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #define MAXN 815 #define INF 1e8 using namespace std; bool dp[801][801]; int a[44]; int n,sum,p; int main() { while(scanf("%d",&n)!=EOF) { 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; p=sum/2; for(int i=0;i<n;i++) { for(int j=p;j>=0;j--) { for(int k=j;k>=0;k--) { if((j>=a[i]&&dp[k][j-a[i]])||(k>=a[i]&&dp[k-a[i]][j])) dp[k][j]=1; } } } int ans=-1; for(int i=p;i>=1;i--) { for(int j=i;j>=1;j--) { if(dp[j][i]) { int c=sum-i-j; if(i + j > c && i + c > j && j + c > i) { double px=(i+j+c)*1.0/2; int temp=(int)(sqrt(px*(px-i)*(px-j)*(px-c))*100); if(ans<temp) ans=temp; } } } } if(ans) printf("%d\n",ans); else printf("-1\n"); } return 0; }