uva 1354 Mobile Computing ——yhx

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cstring>
 4 struct node
 5 {
 6     int fat,lson,rson;
 7     double wei;
 8 }tree[500];
 9 double w[10],lim,ans;
10 int n;
11 double max(double x,double y)
12 {
13     return x>y?x:y;
14 }
15 void calc_sub(int p,double &l,double &r)
16 {
17     int i,j,k;
18     double l1,r1,l2,r2,x,y;
19     if (tree[p].lson)
20     {
21         calc_sub(tree[p].lson,l1,r1);
22         calc_sub(tree[p].rson,l2,r2);
23     }
24     else
25       l1=r1=l2=r2=0;
26     x=tree[tree[p].rson].wei/tree[p].wei;
27     y=tree[tree[p].lson].wei/tree[p].wei;
28     l=max(l1+x,l2-y);
29     r=max(r1-x,r2+y);
30 }
31 void calc()
32 {
33     int i,j,k,p;
34     double l,r;
35     for (i=1;i<=2*n-1;i++)
36       if (tree[i].fat==0)
37       {
38           calc_sub(i,l,r);
39           if (l+r<lim)
40             ans=max(ans,l+r);
41           break;
42       }
43 }
44 void dfs(int p)
45 {
46     int i,j;
47     if (p==n-1)
48     {
49         calc();
50         return;
51     }
52     for (i=1;i<=n+p;i++)
53       for (j=1;j<=n+p;j++)
54         if (i!=j&&tree[i].fat==0&&tree[j].fat==0)
55         {
56             tree[i].fat=tree[j].fat=n+p+1;
57             tree[n+p+1].lson=i;
58             tree[n+p+1].rson=j;
59             tree[n+p+1].wei=tree[i].wei+tree[j].wei;
60             dfs(p+1);
61             tree[i].fat=tree[j].fat=tree[n+p+1].lson=tree[n+p+1].rson=tree[n+p+1].wei=0;
62         }
63 }
64 int main()
65 {
66     int i,j,k,p,q,x,y,z,t;
67     scanf("%d",&t);
68     for (i=1;i<=t;i++)
69     {
70         memset(tree,0,sizeof(tree));
71         memset(w,0,sizeof(w));
72         scanf("%lf",&lim);
73         scanf("%d",&n);
74         for (j=1;j<=n;j++)
75           scanf("%lf",&w[j]);
76         for (j=1;j<=n;j++)
77           tree[j].wei=w[j];
78         ans=-1;
79         dfs(0);
80         if (ans<0) printf("-1\n");
81         else printf("%.9lf\n",ans);
82     }
83 }

因为数据范围并不大,所以可以枚举。

枚举的方法是枚举二叉树,之后计算每棵树的答案。

枚举的时候,每次选择两个没有父节点的节点连接,n-1次之后即得一棵二叉树。

计算的时候,分别计算两棵子树的宽,再结合本节点天平的宽。

有一个小技巧,由于计算时子程序要返回两个值(最左长度和最右长度),不能直接写成返回值,所以可以用实参引用传值。

posted @ 2016-03-30 23:43  Orion_7  阅读(238)  评论(0编辑  收藏  举报