链接:点击打开链接
题意:n根木棍组成任意多的三角形,使得面积和最大
代码:
#include <vector>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
int s;
double area;
};
vector<node> sta;
int a[15];
double dp[1<<13];
int main(){
int n,i,j,k,tmp,siz;
double p,are,ans;
while(scanf("%d",&n)!=EOF&&n){
for(i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
sta.clear();
for(i=0;i<n;i++){ //预处理出所有状态和每个状态对应的面积
for(j=i+1;j<n;j++){
for(k=j+1;k<n;k++){
if(a[i]+a[j]>a[k])
if(a[j]-a[i]<a[k]){
tmp=(1<<i)|(1<<j)|(1<<k);
p=(a[i]+a[j]+a[k])*0.5;
are=sqrt(p*(p-a[i])*(p-a[j])*(p-a[k]));
sta.push_back((node){tmp,are});
}
}
}
}
for(i=0;i<(1<<n);i++)
dp[i]=0;
siz=sta.size();
for(i=0;i<(1<<n);i++){ //直接状态压缩进行转移
for(j=0;j<siz;j++){
if((i&sta[j].s)==0)
dp[i|sta[j].s]=max(dp[i|sta[j].s],dp[i]+sta[j].area);
}
}
ans=0;
for(i=0;i<(1<<n);i++)
ans=max(ans,dp[i]);
printf("%.2lf\n",ans);
}
return 0;
}