1261-Mobile Computing
問題概要
ある場所にはたくさんの美しい石がある.そして,そこに住んでいる人々は石を集めることが好きであった..
そして人々は集めた石を持って帰り美しいModileアートを作るのであった.
さてここではModileは以下のように再帰的に定義される.
・紐によって吊されている石
・長さが1の棒で,両端にさらに"Mobile"が吊されている.そして,この棒は重心に紐で吊されている.
部屋の幅を越えず,かつ全ての石を使ったMobileのうち,もっとも幅が広いものを求めよ
解法
全探索して,全ての作れるMobileを求める.
実装(C++)
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <climits> #include <queue> #include <stack> #include <algorithm> #include <list> #include <vector> #include <set> #include <map> #include <iostream> #include <deque> #include <complex> #include <string> #include <iomanip> #include <sstream> #include <bitset> #include <valarray> #include <fstream> using namespace std; typedef long long int lli; typedef unsigned int uint; typedef unsigned char uchar; typedef unsigned long long ull; #define REP(i,x) for(int i=0;i<(int)(x);i++) #define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++) #define RREP(i,x) for(int i=(x);i>=0;i--) #define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++) #define dout(...) printf(__VA_ARGS__);fflush(stdout); int s; int stone[6]; double width; int T; struct Rod{ Rod *left,*right; int lw,rw,w; int used; Rod(int ww=0,int us=0){ left=right=0;lw=rw=w=0; w=ww;used=us; } }; vector<Rod> rods[7];//i個用いて作れるモビール double lx,rx; void dfs(const Rod &r,double x){ //cout<<x<<endl; lx=min(lx,x);rx=max(rx,x); if(!r.left)return;//何もない double n=r.lw,m=r.rw; //cout<<n<<","<<m<<endl; double a=m/(n+m); double b=1-a; dfs(*r.right,x+b); dfs(*r.left,x-a); } void solve(){ REP(i,s){ rods[1].push_back(Rod(stone[i],1<<i)); } for(int i=1;i<=s;i++){ for(int j=1;j<=i;j++){ if(i+j>s)continue; for(int x=0;x<(int)rods[i].size();x++){ for(int y=0;y<(int)rods[j].size();y++){ if(j==i&&x<=y)continue; if(rods[i][x].used&rods[j][y].used)continue; Rod next; next.left=&rods[i][x]; next.right=&rods[j][y]; next.lw=rods[i][x].w; next.rw=rods[j][y].w; next.w=next.lw+next.rw; next.used=rods[i][x].used|rods[j][y].used; rods[i+j].push_back(next); swap(next.left,next.right); swap(next.lw,next.rw); rods[i+j].push_back(next); } } } } double ans=-1; REP(i,rods[s].size()){ lx=rx=0; dfs(rods[s][i],0); if(rx-lx<=width){ ans=max(ans,rx-lx); } } if(ans<0)cout<<"-1"<<endl; else cout<<setprecision(15)<<setiosflags(ios::fixed)<<ans<<endl; } int main(){ cin>>T; while(T--){ cin>>width; cin>>s; REP(i,s)cin>>stone[i]; REP(i,7)rods[i].clear(); solve(); } return 0; }