题意:
给你 n 个棍子长度,求用这些棍子所能组成的多个三角形的总面积最大值
解法:
用状压表示每根棍子的使用情况,最多12根棍子,那么最大的状态数为2^12-1,可用longlong保存
若状态数二进制为 i =1001001(2),则表示第1,4,7根棍子已经使用,故后面不能再使用
dp[i] 表示 状态数 i 中剩下的棍子中所能取得的最大总三角形面积值
然后暴力递归记忆化即可
#include<bits/stdc++.h> #define ll long long using namespace std; int a[20]; int n; int now=0; double dp[1000006]; double dfs(int now) { if(dp[now]!=-1) return dp[now]; double ans=0; for(int i=0;i<n;i++) { if((now>>i) %2) continue; for(int j=i+1;j<n;j++) { if((now>>j) %2) continue; for(int k=j+1;k<n;k++) { if((now>>k) %2) continue; int aa=(now>>i) %2; int bb=(now>>j)% 2; int cc=(now>>k)% 2; int nnow=now; if(aa+bb+cc==0) { nnow|=(1<<i); nnow|=(1<<j); nnow|=(1<<k); aa=a[i]; bb=a[j]; cc=a[k]; int b[4]; b[0]=aa; b[1]=bb; b[2]=cc; sort(b,b+3); if(b[0]+b[1]<=b[2]) continue; aa=b[0]; bb=b[1]; cc=b[2]; double p=(aa+bb+cc)/2.0; double s=sqrt(p*(p-aa)*(p-bb)*(p-cc)); ans=max(ans,s+dfs(nnow)); } else continue; } } } dp[now]=ans; return ans; } int main() { while(~scanf("%d",&n)&&n) { for(int i=0;i<=1e6;i++) dp[i]=-1; for(int i=0;i<n;i++) { scanf("%d",&a[i]); } double ans=0; ans=dfs(0); printf("%.2lf\n",ans); } }
Little Zu Chongzhi‘s Triangles 状压DP
最新推荐文章于 2021-03-31 13:16:45 发布