搜索 【uva1354】 Mobile Computing (练习题7-7 天平难题)

7-7天平难题(Mobile Computing,uva 1354)
(mobile.cpp,Time Limit:3000MS )

题目描述:
给出房间的宽度r和s个挂坠的重量wi,设计一个尽量宽(但宽度不能超过房间宽度r)的天平,挂着所有挂坠。
天平由一些长度为1的木棍组成。木棍的每一端要么挂一个挂坠,要么挂另外一个木棍。如图1所示,设n和m分别是两端的总重量,要让天平平衡,必须满足n*a=m*b。

这里写图片描述

例如:如果有3个重量分别为1,1,2的挂坠,有3种平衡的天平,如下图所示:

这里写图片描述

挂坠的宽度忽略不计,且不同的子天平可以相互重叠。如下图所示,宽度为(1/3)+1+(1/4)。
这里写图片描述

输入格式:
输入第一行为数据组数。每组数据前两行为房间宽度r和挂坠数目s (0 < r < 10,1<=s<=6)。以下s行为一个挂坠的重量wi(1<=wi<=1000)。输入保证不存在天平的宽度恰好在r-10^(-5)和r+10^(-5)(这样可以保证不会出现精度问题)。

输出格式:
对于每组数据,输出最优天平的宽度。如果无解,输出-1。你的输出和标准答案的绝对误差不应超过10^(-8)。

样例输入:

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

样例输出:

-1
1.3333333333333335
1.6666666666666667
1.5833333333333335
1.7142857142857142

题目分析:(搜索)
天平的形态最后可以看成二叉树,所以问题转化成了我们有一堆点(点数还不超过6),要把这一堆点合成一颗树。我们可以用哈弗曼树的想法,每次把两个节点合成一个新的节点,最终只剩下一个节点,就是一组可行解,更新答案。

但是我们不知道每次要合并哪两个点,因为层数很少,所以可以暴力枚举。

这样这道题就做完了,我的做法灰常辣鸡,没有用什么高端的剪枝和搜索技巧。
想知道更多搜索基础知识和优化技巧,可以到其他神犇的博客学习。

注意事项:
在合并两个点的时候,有可能出现这样的情况:
这里写图片描述

红色是一个节点,蓝色是一个节点。
把这两个点合到一起的时候,右边的那只明显越界了啊,把左边那只给包起来了,所以我们可以发现,这个节点的左边界不仅仅跟左边的节点有关系,还跟右边的节点有关系,这种情况需要在合并的时候判断出来。

代码如下:(代码写的很辣鸡,勿喷)

#include<cstdio>
#include<iostream>
using namespace std;
struct balance{
    double w,ls,rs;
    balance operator + (const balance c)
    {
        balance z;
        z.w=w+c.w;
        double l=c.w/(w+c.w);
        double r=w/(w+c.w);
        z.ls=max(l+ls,c.ls-r);
        z.rs=max(r+c.rs,rs-l);
        return z;
    }
}a[10];

double r,ans;
int s,T;

void dfs(int c)
{
    if(c==s)
    {
        double cs=a[1].ls+a[1].rs;
        if(cs<=r && cs>ans) ans=cs;
        return;
    }
    balance b[10],d[10];
    for(int i=1;i<=s-c+1;i++) b[i]=a[i];
    for(int i=1;i<=s-c+1;i++)
        for(int j=1;j<=s-c+1;j++)
    {
        if(i==j) continue;
        for(int k=1;k<=s-c+1;k++) a[k]=b[k];
        int top=0;
        for(int k=1;k<=s-c+1;k++)
            if(k!=i && k!=j) d[++top]=a[k];
        d[++top]=a[i]+a[j];
        for(int k=1;k<=top;k++) a[k]=d[k];
        dfs(c+1);
    }
}

int main()
{
    scanf("%d",&T);
while(T--)
{
    scanf("%lf%d",&r,&s);
    for(int i=1;i<=s;i++)
    {
        scanf("%lf",&a[i].w);
        a[i].ls=0;
        a[i].rs=0;
    }
    ans=-1;
    dfs(1);
    printf("%.10lf\n",ans);
}
    return 0;
}
HCIE-云计算实验室备考--第五题: 第五题要求我们将一个传统的单机应用迁移到云平台上,带有扩展性和弹性。首先,我们需要了解传统的单机应用的特点和局限性。传统的单机应用只能在单个物理机上运行,对于资源的分配和请求相对固定,无法根据需求进行自动的扩展。而云平台则提供了更灵活的资源调度和管理功能,能够根据实际需求进行动态的扩容和缩容。 在进行迁移之前,我们需要对应用进行评估和改造。首先,我们需要将应用进行拆分,将不同的模块拆分为独立的服务。这样可以实现服务的粒度化,提高系统的可扩展性。接下来,我们需要对应用进行重构,将传统的单机应用改造为分布式的服务,通过服务间的通信和协作来实现应用的功能。同时,我们还需要对应用进行容错处理,增加冗余和备份机制,确保系统的高可用性。 在迁移到云平台后,我们需要使用云平台提供的服务来实现我们的扩展性和弹性要求。首先,我们可以借助云平台的弹性计算功能,根据实际负载的变化来自动进行资源的扩展和缩容。其次,我们可以利用云平台提供的负载均衡和自动扩展策略,来实现对应用的动态调度和管理。此外,我们还可以利用云平台的存储和数据库服务,来实现数据的存储和管理,提高系统的可靠性和性能。 总之,通过将传统的单机应用迁移到云平台上,并进行相应的改造和优化,我们可以实现应用的扩展性和弹性。这不仅可以提高系统的性能和可用性,还可以大大降低应用的运维成本。因此,学习和掌握这些迁移和优化的技术是备考中非常重要的一部分。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值