hdu 5135

Posted liqgnonqfu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5135相关的知识,希望对你有一定的参考价值。

题目大意:

       有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
");
 76             scanf("%d",&n);
 77             continue;
 78         }
 79         if(trn==1)
 80         {
 81             printf("%.2lf
",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
",ans);
104         scanf("%d",&n);
105     }
106     return 0;
107 }
View Code

 

以上是关于hdu 5135的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5135(再思考)

hdu 5135

hdu-5127------hdu5137

hdu 3339(最短路+01背包)

LA5135 Mining Your Own Business

LA 5135 井下矿工(点—双连通分量模板题)