给N跟棍子,要组合成三角形,并把所有的棍子全部用上,求最大的三角形面积。
刚看到题目的时候就定位为DP,但是对于找状态转移方程很模糊,后面说这就是一个01背包问题,以三角形的两条边为多重背包。
这样想想还蛮简单的,数据比较小,滚子数小于40,所以可以把每个满足情况的三角形都算一次面积,最后去最大值就可以了。
由于最长边不可能大于和的一半,所以二维数组开800就可以了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int dp[808][808],q[48];
int Heron(int a,int b,int c){
double p=(a+b+c)*1.0/2; //注意这里要乘1.0,把整形转换为浮点型
int s;
return s=(int )(sqrt(p*(p-a)*(p-b)*(p-c))*100);
}
int main(){
int n,i,j,k,z,sum;
while(~scanf("%d",&n)){
sum=0;
for(i=1;i<=n;i++){
scanf("%d",&q[i]);
sum+=q[i];
}
int half=sum/2;
int ant,maxx=0;
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(i=1;i<=n;i++){
for(j=half;j>=0;j--){ //j和k代表三角形的两条边长
for(k=j;k>=0;k--){
if((j >= q[i] && dp[j-q[i]][k] == 1) || (k >=q[i] && dp[j][k-q[i]] == 1) ){ //只要能放进任意一条就满足条件了
z=sum-j-k;
dp[j][k]=1;
if(k+j > z && k+z >j && j+z > k){
ant=Heron(j,k,z);
if(ant > maxx) maxx=ant;
}
}
}
}
}
if(maxx==0) {
printf("-1\n"); continue;
}
printf("%d\n",maxx);
}
return 0;
}
坚持中。。。。