题意是给出最对12条边你 问最大可组成三角形面积是多大 (可有多个三角形) 典型的状态压缩 (最多12条边)
思路:
先暴力枚举所有可能三角形的面积 然后再根据状态压缩来做 最多可组成n/3个三角形 对每个三角形都记录三边或(运算) 和面积 然后判断进行合并 (根据且运算) 就行了
#include
#include
#include
#include
using namespace std
; double dp
[1
<<14
]; double max
(double a
,double b
) { return a
>b
?a
:b
; } struct node
{ int pp
; double area
; }cont
[1
<<14
]; int main() { int n
,i
,j
,k
; int num
[15
]; double S
; while(~scanf
("%d"
,&n
),n
) { for(i
=1
;i
<=n
;i
++) scanf
("%d"
,&num
[i
]); memset
(dp
,0
,sizeof(dp
)); int t
=0
; S
=0
; for(i
=1
;i
<=n
;i
++) for(j
=i
+1
;j
<=n
;j
++) { for(k
=j
+1
;k
<=n
;k
++) { if(num
[i
]+num
[j
]>num
[k
]&&num
[i
]+num
[k
]>num
[j
]&&num
[j
]+num
[k
]>num
[i
]) { double p
=1.0
*(num
[i
]+num
[j
]+num
[k
])/2
; t
++; double s
=sqrt
(p
*(p
-num
[i
])*(p
-num
[j
])*(p
-num
[k
])); cont
[t
].pp
=(1
<<i
)|(1
<<j
)|(1
<<k
); dp
[(1
<<i
)|(1
<<j
)|(1
<<k
)]=cont
[t
].area
=s
; } } } for(i
=1
;i
<(1
<<(n
+1
));i
++) { for(j
=1
;j
<=t
;j
++) { if((i
&cont
[j
].pp
)==0
) { dp
[i
|cont
[j
].pp
]=max
(dp
[i
|cont
[j
].pp
],dp
[i
]+cont
[j
].area
); if(dp
[i
|cont
[j
].pp
]>S
) S
=dp
[i
|cont
[j
].pp
]; } } } printf
("%.2lf\n"
,S
); } return 0
; }