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;
}