uva1388 - Graveyard

链接

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4134

题解

分析样例之后,我假设出这样的算法:
固定第一个点不动,其余的点都移到离自己最近的点。

固定第一个点不动一定是最优解吗?

假设我们已经找到了最优解,且没有任何一个点是不移动的,那么我们可以进行旋转,在这个过程中一定可以使得答案变小或变大、或者不变,这取决于旋转的方向和点的分布,如果顺时针旋转使得答案变小,那么逆时针旋转就会使得答案变大,总之你就能构造出一组更优解,换言之,一开始的假设是不成立的,而当我旋转到某个点和原来的位置重合时(一个点和其他点的原始位置重合也算),就停下,这样就以定能构造出一组更优解。
也就是说,一定存在一组最优解,使得某些点不需要移动。
而由于这个图形具有高度的对称性,你让任何一个点一开始不动都是一样的,因此我们选择最好处理的一号点。

两个点不会移动到同一个地方吗?

不会
这里写图片描述
假设上述情况存在,如图所示,红色代表目标状态,绿色代表原始状态,首先可以肯定的是两个红点之间最多有一个绿点(因为绿点间的距离一定大于红点间的距离),那么在如图情形下,
b<a,c<d b < a , c < d
所以 b+c<a+d b + c < a + d
所以 b+c+b+c<a+b+c+d b + c + b + c < a + b + c + d
所以 2n<2n+m 2 n < 2 n + m
所以 n>n+m n > n + m
m<0 m < 0
这显然是不可能的,所以我们一开始的假设就不成立,也就不存在两个点会移动到同一个点的情况

代码

#include <cstdio>
#include <cmath>
#include <algorithm>
#define maxn 2018
using namespace std;
double n, m, pos1[maxn], pos2[maxn];
int main()
{
    int i, j;
    double ans, t;
    while(~scanf("%lf%lf",&n,&m))
    {
        for(i=1;i<=n;i++)pos1[i]=(i-1)*10000.0/n;
        for(i=1;i<=n+m;i++)pos2[i]=(i-1)*10000.0/(n+m);
        for(i=1,ans=0.0;i<=n;i++)
        {
            t=1e100;
            for(j=1;j<=n+m;j++)t=min(t,fabs(pos1[i]-pos2[j]));
            ans+=t;
        }
        printf("%.10lf\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值