题意是给出最对12条边你 问最大可组成三角形面积是多大 (可有多个三角形) 典型的状态压缩 (最多12条边)
思路:
先暴力枚举所有可能三角形的面积 然后再根据状态压缩来做 最多可组成n/3个三角形 对每个三角形都记录三边或(运算) 和面积 然后判断进行合并 (根据且运算) 就行了
#include<stdio.h> #include<string.h> #include<cmath> #include<iostream> 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; }
时间: 2024-10-26 19:55:44