0
点赞
收藏
分享

微信扫一扫

【51Nod 1110 】距离之和最小 V3


Description

X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i]。该点到其他点的带权距离 = 实际距离 * 权值。求X轴上一点使它到这N个点的带权距离之和最小,输出这个最小的带权距离之和。

Solution

看到这个n个点到一个点的“距离和最小”,就要想到中位数。
但是它带权,那么怎么办?
其实一个坐标为x,带了个权w,就相当于有w个x,因为如果最优位置在y处,前者的答案=abs(x-y)*w,后者也是等于=abs(x-y)*w。
那么每个x拆成w个,然后再求一个中位数就好了。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=10007;
typedef long long ll;;
ll i,j,k,l,t,n,m,ans;
struct node{
ll a,b;
}a[maxn];
bool cmp(node x,node y){return x.a<y.a;}
int main(){
scanf("%lld",&n);
fo(i,1,n)scanf("%lld%lld",&a[i].a,&a[i].b),t+=a[i].b;
sort(a+1,a+n+1,cmp);
t=(t+1)/2;
fo(i,1,n){
if(l+a[i].b<t){
l+=a[i].b;
continue;
}
k=i;
break;
}
fo(i,1,n){
ans+=abs(a[i].a-a[k].a)*a[i].b;
}
printf("%lld\n",ans);
}


举报

相关推荐

0 条评论