UvaLive 3403 Mobile Computing 枚举二叉树

来源:互联网 发布:李昌钰蓝可儿 知乎 编辑:程序博客网 时间:2024/05/16 04:57

题目链接:点击打开链接

题意:

给定房间宽度r和s个石头重量

设计一个尽量宽但宽度不超过房间宽度r的天平,使得能把所有石头放在天平上

(天平的一端要么挂一个石头,要么挂一个天平)

天平的平衡满足杠杆原理(两端重量的比值与两端距离悬挂天平点的距离成反比,每根天平杆长度为1)

输出最大的宽度(若不能把石头都挂上输出-1)

思路:

枚举计算每一个状态时的最大宽度。

若这个状态只有一个石头,那么得到的天平就认为是(0,0) (0,0)的意思是以天平支点为准,向左延展的长度和向右延展的长度

否则一定是由2个子状态合成,即2个子天平拼出来。

枚举其中一个子天平的状态,另一个子天平的状态异或一下就得到了,

则向左延展的长度为 max(父天平向左延展的长度+左子天平向左延展的长度,右子天平向左延展的长度-父天平向左延展的长度)

向右延展长度同理。


import java.io.PrintWriter;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Comparator;import java.util.Iterator;import java.util.LinkedList;import java.util.PriorityQueue;import java.util.Scanner;import java.util.TreeSet;import java.util.Queue;public class Main {class Node{double l, r;Node(double l, double r){this.l = l;this.r = r;}}static int N = 65;double R; int s;double[] a = new double[10], w = new double[N];ArrayList<Node>[] E = new ArrayList[N];void work() {for(int i = 0; i < N; i++)E[i] = new ArrayList();int T = cin.nextInt();while(T-->0){R = cin.nextDouble();s = cin.nextInt();for(int i = 0; i < s; i++)a[i] = cin.nextDouble();for(int i = 0; i < (1<<s); i++){w[i] = 0;for(int j = 0; j < s; j++)if(((1<<j)&i)>0)w[i] += a[j];}for(int i = 0; i < N; i++) E[i].clear(); for(int st = 1; st < (1<<s); st++){            if(0 == ((st-1)&st)) {//若这个状态里只有一个石头                E[st].add(new Node(0,0));                continue;            }            for(int sb=(st-1)&st;sb > 0;sb=(sb-1)&st){                int sa=st^sb;                double rs=w[sb]/w[st],ls=w[sa]/w[st];                for(int i = 0; i < E[sb].size(); i++)                for(int j = 0; j < E[sa].size(); j++)                {                    double l=max(E[sb].get(i).l+ls,E[sa].get(j).l-rs);                    double r=max(E[sb].get(i).r-ls,E[sa].get(j).r+rs);                    if(r+l>R) continue;                    E[st].add(new Node(l,r));                }            }        } double ans = -1; for(int i = 0; i < E[(1<<s)-1].size(); i++) ans=max(ans,E[(1<<s)-1].get(i).l+E[(1<<s)-1].get(i).r); out.println(ans); }}Main() {cin = new Scanner(System.in);out = new PrintWriter(System.out);}public static void main(String[] args) {Main e = new Main();e.work();out.close();}public Scanner cin;public static PrintWriter out;int max(int x, int y) {return x > y ? x : y;}int min(int x, int y) {return x < y ? x : y;}double max(double x, double y) {return x > y ? x : y;}double min(double x, double y) {return x < y ? x : y;}}


0 0
原创粉丝点击