题目链接:
http://poj.org/problem?id=1948
题目大意:给最多40根木棍,每根长度不超过40,要用完所有的木棍构成面积最大的三角形,求出最大的面积。
思路:设f[i][j]为第一条边长度为i,第二条边长度为j是否可行
状态转移方程:
if(j>=a[i])
f[j][k]=f[j][k]||f[j-a[i]][k]
if(k>=a[i])
f[j][k]=f[j][k]||f[j][k-a[i]]
#include
#include
#include
using namespace std;
int f[810][810];
int a[50];
void swap(int &a, int &b){
int tmp = a;
a = b;
b = tmp;
}
int san(int a,int b,int c)
{
if(a > b) swap(a,b);
if(a > c) swap(a,c);
if(b > c) swap(b,c);
if(a + b < c) return -1;
double p = (a + b + c) * 1.0 / 2;
double ret;
ret = sqrt(p * (p-a) * (p-b) * (p-c)) * 100;
return (int)ret;
}
int main(){
int n;
scanf("%d",&n);
int sum = 0;
for (int i = 0; i < n; i ++){
scanf("%d",&a[i]);
sum += a[i];
}
memset(f, 0, sizeof(f));
f[0][0] = 1;
int ban = sum / 2;
for (int k = 0; k < n; k ++){
for (int i = ban; i >= 0; i --){
for (int j = ban; j >= 0; j --){
if (i - a[k] >= 0){
f[i][j] = f[i][j] | f[i - a[k]][j];
}
if (j - a[k] >= 0){
f[i][j] = f[i][j] | f[i][j - a[k]];
}
}
}
}
int max = -1;
for (int i = 1; i <= ban; i ++){
for (int j = 1; j <= ban; j ++){
if (f[i][j]){
if (san(i, j, sum - i - j) > max){
max = san(i, j, sum - i - j);
}
}
}
}
printf("%d\n", max);
return 0;
}