UVA 1354 Mobile Computing(暴力)

来源:互联网 发布:网络直播方案 编辑:程序博客网 时间:2024/06/02 10:34

There is a mysterious planet called Yaen,whose space is 2-dimensional. There are many beautiful stones on the planet,and the Yaen people love to collect them. They bring the stones back home andmake nice mobile arts of them to decorate their 2-dimensional living rooms.

Intheir 2-dimensional world, a mobile is defined recursively as follows: • astone hung by a string, or

•  a rod of length 1 with twosub-mobiles at both ends; the rod is hung by a string at the center of gravityof sub-mobiles. When the weights of the sub-mobiles aren and m, and theirdistances from the center of gravity are aand b respectively, the equation n×a= m×bholds.

For example, if yougot three stones with weights 1, 1, and 2, here are some possible mobiles andtheir widths:

Given the weights ofstones and the width of the room, your task is to design the widest possiblemobile satisfying both of the following conditions.

•  It uses all the stones.

•  Its width is less than thewidth of the room.

You should ignore the widths of stones.

In some cases twosub-mobiles hung from both ends of a rod might overlap (see the figure on theright). Such mobiles are acceptable. The width of the example is (1/3) + 1 + (1/4).

Input

Thefirst line of the input gives the number of datasets. Then the specified numberof datasets follow. A dataset has the following format.

r s w1

...

ws

r is a decimal fraction representing the width of the room, whichsatisfies 0< r < 10. s is the number of the stones. You mayassume 1 ≤ s ≤ 6. wi is the weight of the i-th stone, which is an integer. You mayassume 1 ≤wi ≤ 1000.

Youcan assume that no mobiles whose widths are between r−0.00001 andr+0.00001can be made of given stones.

Output

For each dataset in the input, one linecontaining a decimal fraction should be output. The decimal fraction shouldgive the width of the widest possible mobile as defined above. An output lineshould not contain extra characters such as spaces.

In case there is no mobile whichsatisfies the requirement, answer ‘-1’ instead.

The answer should nothave an error greater than 0.00000001. You may output any numb er of digitsafter the decimal point, provided that the ab ove accuracy condition issatisfied.

Sample Input

5

1.3

3

1

2

1

1.4

3

1

2

1

2.0

3

1

2

1

1.59

4

2

1

1

3

1.7143

4

1

2

3

5

Sample Output

-1

1.3333333333333335

1.6666666666666667

1.5833333333333335

1.7142857142857142



【思路】

所有的坠子和杠杆可以看做节点,构成一棵二叉树,暴力枚举二叉树的组成方式,再对宽度进行计算,就可以得到答案。暴力枚举时需要用到回溯的方式。


【代码】

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int MAXN=15;const double EPS=1e-9;double room,ans;int t,s,cnt;int w[MAXN];bool ava[MAXN];double l[MAXN],r[MAXN];void build_tree(int deep){    if(deep==s)return;    for(int i=1;i<=11;i++)        if(ava[i]){            ava[i]=false;            for(int j=1;j<=11;j++)                if(ava[j]){                    double left=max(l[i],l[j]-1),right=max(r[j],r[i]-1);                    if(left+right+1>room-EPS)continue;                    if(deep==s-1)ans=max(ans,left+right+1);                    ava[j]=false;                    cnt++;                    w[cnt]=w[i]+w[j];                    l[cnt]=left+(double)w[j]/w[cnt];                    r[cnt]=right+(double)w[i]/w[cnt];                    ava[cnt]=true;                    build_tree(deep+1);                    ava[cnt]=false;                    cnt--;                    ava[j]=true;                }            ava[i]=true;        }}int main(){    scanf("%d",&t);    while(t--){        scanf("%lf",&room);        scanf("%d",&s);        cnt=0;        memset(ava,false,sizeof(ava));        for(int i=1;i<=s;i++){            scanf("%d",&w[i]);            ava[i]=true;            cnt++;        }        if(s==1)            printf("0.0000000000000000\n");        else{            memset(l,0,sizeof(l));            memset(r,0,sizeof(r));            ans=0;            build_tree(1);            if(fabs(ans)<EPS)                printf("-1\n");            else                printf("%.16f\n",ans);        }    }    return 0;}


原创粉丝点击