Tower( rms模拟4-3 ) * *(推理)

Tower(tower.cpp)
试题描述:
DR在平面上放置N个整数坐标点。并假定将点(x0,y0)移动到(x1,y1),所需的代价为|x1-x0|+|y1-y0|。使得K(K=1,…,N)个点在同一位置上最少需要的代价。
输入格式:第一行一个正整数N;接下来N行,每行
两个正整数xi和yi,为第i个点的坐标,不超过10^6;
输出格式:输出共N行,第i行为使得有i个点在同一位置的最少代价。
输入样例:
4
15 14
15 16
14 15
16 15
输出样例:
0
2
3
4
数据规模:
对于100%的数据,满足1<=N<=50。

题解:

最优解必定是在(xi,yi)这些位置上的,因此只要枚举这些位置(共N2个),然后将所有点与这个位置的距离D[i]从小到大排序,然后S[i] = D[1] + D[2] + … +D[i]。
那么Ans[k] = min { Ans[k] , S[k] }。

时间复杂度:O(N^4logN)
空间复杂度:O(N)

代码

#include<bits/stdc++.h>
#define F( i,a,b ) for( int i=(a);i<=(b);i++ )
#define F_2( i,a,b ) for( int i=(a);i>=(b);i-- )
#define N 101
#define M 10001
#define LL long long
#define oo 0x7fffffff
using namespace std;

int read()
{
    int f=1,s=0;
    char ch=getchar();
    while( ch>'9' || ch<'0' ) { if( ch=='-' ) f=-1; ch=getchar(); }
    while( ch<='9' && ch>='0' ) { s=( s<<1 )+( s<<3 )+ch-'0'; ch=getchar(); }
    return f*s;
}

int m,n;
int tot,cnt,ans[N];
int x[N],y[N],d[N],s[N];

int main()
{
    freopen( "tower.in","r",stdin );
    freopen( "tower.out","w",stdout );
    n=read();
    F( i,1,n )
    {
        x[i]=read();
        y[i]=read();
    }
    fill( ans+1,ans+n+1,oo );
    F( i,1,n )
    {
        F( j,1,n )
        {
            int tx,ty;
            tx=x[i],ty=y[j];
            F( k,1,n )
                d[k]=abs( tx-x[k] )+abs( ty-y[k] );
            sort( d+1,d+n+1 );
            F( i,1,n )
            {
                s[i]=s[i-1]+d[i];
            }
            F( i,1,n )
            {
                ans[i]=min( ans[i],s[i] );
            }   
        }
    }
    F( i,1,n )
        cout<<ans[i]<<endl;
    return 0;
}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值