标签:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 /** 6 思路:在每一个根节点枚举左右子树 7 8 学习: 9 (1)枚举子集的方法 例如 枚举 s = 100101 的子集 10 for(int l = (s-1)&s , l > 0 ; l = (l-1) & s){ 11 int r = s ^ l; 12 (2)思考:如何表示 左边距离 右边距离 。 该点的左臂/右臂长度由子集决定:-sumw[r]/(sumw[l] + sumw[r]) + node[l][i].l 13 sumw[i] :表示子集i 的重量 14 node[i].l : 表示子集 i 的左臂长度 15 左臂+左子天平的左臂 与 右子天平的左臂-右臂 谁更小 16 右臂+右子天平的右臂 与 左子天平的右臂-左臂 谁更大 17 */ 18 19 20 struct Node{ 21 double l,r; //存放该点的子天平 最左延伸点,最右延伸点 22 Node(){} 23 Node(double ll,double rr):l(ll),r(rr){} 24 }; 25 int n; 26 double r,w[12],ans,sumw[1<<6]; 27 int vis[1<<6]; 28 vector<Node> node[1<<6]; 29 int bitcount(int x){ 30 if(!x) return 0; 31 return bitcount(x>>1) + (x&1); 32 } 33 void dfs(int s){ 34 if(vis[s]) return ; 35 vis[s] = true; 36 if(bitcount(s) == 1){ 37 node[s].push_back(Node{0,0}); 38 return ; 39 } 40 for(int l = (s-1)&s ; l > 0 ; l = (l-1) & s){ 41 int r = s ^ l; 42 dfs(l); dfs(r); // 一个根节点 的 两个子集的所有方案. node[l].size() 左边方案数 node[r].size() 右边方案数 43 for(int i = 0 ; i < node[l].size() ; i ++){ 44 for(int j = 0 ; j < node[r].size() ; j ++){ 45 double ll = min(-sumw[r] / (sumw[l] + sumw[r]) + node[l][i].l, sumw[l] / (sumw[l] + sumw[r]) + node[r][j].l); 46 double rr = max(sumw[l] / (sumw[l] + sumw[r]) + node[r][j].r, -sumw[r] / (sumw[l] + sumw[r]) + node[l][i].r); 47 node[s].push_back(Node(ll, rr)); 48 } 49 } 50 } 51 } 52 53 void solve(){ 54 memset(vis,0,sizeof(vis)); 55 memset(node,0,sizeof(node)); 56 ans = -1; 57 int s = (1<<n) - 1; 58 dfs(s); 59 for(int i = 0 ; i < node[s].size() ; i ++){ 60 if(node[s][i].r - node[s][i].l < r && node[s][i].r - node[s][i].l > ans){ 61 ans = node[s][i].r - node[s][i].l; 62 } 63 } 64 if (ans == -1) printf("-1\n"); 65 else printf("%.10lf\n", ans); 66 } 67 68 int main(){ 69 int T; 70 scanf("%d",&T); 71 while(T--){ 72 scanf("%lf%d",&r,&n); 73 for(int i = 0 ; i < n ; i ++) scanf("%lf",&w[i]); 74 for(int i = 0 ; i < (1 << n ) ; i ++){ 75 sumw[i] = 0; 76 for(int j = 0 ; j < n ; j ++){ 77 if(i & (1 << j)) sumw[i] += w[j]; 78 } 79 } 80 solve(); 81 } 82 return 0; 83 }
UVA 1354 Mobile Computing(天平难题,枚举子集,递归,好题*)
标签:
原文地址:http://www.cnblogs.com/zstu-jack/p/5468263.html