标签:main img play nod hang space 分享 line 题目
题目大意:
有n根火柴棒,现在将它们拼成若干个三角形,最大化所拼三角形总面积,输出这个最大值。(3 <= N<= 12)
思路:
由于n很小,先找出所有可能的三角形,记录它的面积和所用的火柴。记录所用火柴时,可以用n位二进制表示,用了哪根哪位就记为1。
之后就是类似背包的动规了。
f[i][j]表示到底i个三角形,火柴棒剩余情况为j(同样,剩哪个哪个是1)的最大面积,tri[i].area表示面积,tri[i].stick表示所用火柴。
转移方程:f[i][j]=max(f[i-1][j],f[i-1][j^tri[i].stick]+tri[i].area)或f[i][j]=f[i-1][j];
前者的条件是tri[i].stick是1的位j都是0,即tri[i]&j==0。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 7 using namespace std; 8 9 const int M=(1<<12); 10 11 struct node 12 { 13 double area; 14 int stick; 15 node() 16 { 17 area=0; 18 stick=0; 19 } 20 }tri[300]; 21 int n,sti[20],trn; 22 double f[222][M]; 23 24 int change(int i,int j,int k) 25 { 26 i--;j--;k--; 27 return (1<<i)+(1<<j)+(1<<k); 28 } 29 30 double check(int i,int j,int k) 31 { 32 double ret=0; 33 /* double p=i+j+k; 34 p/=2; 35 ret=sqrt(p*(p-i)*(p-j)*(p-k));*/ 36 double angle=i*i+j*j-k*k; 37 double aa=i*j; 38 angle=angle/(2*aa); 39 angle=sqrt(1-angle*angle); 40 ret=0.5*aa*angle; 41 return ret; 42 } 43 44 double maxx(double a,double b) 45 { 46 if(a>b)return a; 47 else return b; 48 } 49 50 int main() 51 { 52 scanf("%d",&n); 53 while(n) 54 { 55 memset(sti,0,sizeof(sti)); 56 memset(tri,0,sizeof(tri)); 57 for(int i=1;i<=n;i++)scanf("%d",&sti[i]); 58 trn=0; 59 for(int i=1;i<=n;i++) 60 for(int j=i+1;j<=n;j++) 61 for(int k=j+1;k<=n;k++) 62 { 63 if(i!=j&&j!=k&&i!=k) 64 { 65 if((sti[i]+sti[j]>sti[k])&&(sti[i]+sti[k]>sti[j])&&(sti[k]+sti[j]>sti[i])) 66 { 67 trn++; 68 tri[trn].stick=change(i,j,k); 69 tri[trn].area=check(sti[i],sti[j],sti[k]); 70 } 71 } 72 } 73 if(trn==0) 74 { 75 printf("0.00\n"); 76 scanf("%d",&n); 77 continue; 78 } 79 if(trn==1) 80 { 81 printf("%.2lf\n",tri[1].area); 82 scanf("%d",&n); 83 continue; 84 } 85 memset(f,0,sizeof(f)); 86 int tem=(1<<n)-1; 87 for(int i=1;i<=trn;i++) 88 { 89 for(int j=0;j<tem;j++) 90 { 91 f[i][j]=f[i-1][j]; 92 if(!(j&tri[i].stick)) 93 { 94 f[i][j]=maxx(f[i-1][j],f[i-1][j^tri[i].stick]+tri[i].area); 95 } 96 } 97 } 98 double ans=0; 99 for(int i=0;i<tem;i++) 100 { 101 ans=maxx(ans,f[trn][i]); 102 } 103 printf("%.2lf\n",ans); 104 scanf("%d",&n); 105 } 106 return 0; 107 }
标签:main img play nod hang space 分享 line 题目
原文地址:https://www.cnblogs.com/LiqgNonqfu/p/9751336.html