51nod 1110 距离之和最小 V3

基准时间限制:1 秒 空间限制:131072 KB 分值: 40  难度:4级算法题
 收藏
 关注
X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i]。点P到点P[i]的带权距离 = 实际距离 * P[i]的权值。求X轴上一点使它到这N个点的带权距离之和最小,输出这个最小的带权距离之和。
Input
第1行:点的数量N。(2 <= N <= 10000)
第2 - N + 1行:每行2个数,中间用空格分隔,分别是点的位置及权值。(-10^5 <= X[i] <= 10^5,1 <= W[i] <= 10^5)
Output
输出最小的带权距离之和。
Input示例
5
-1 1
-3 1
0 1
7 1
9 1
Output示例
20

看了题解才懂系列.....

如果没有权值,那么我们找点肯定是找最中间那个点,那么有权值呢,我们就将它看成有权值个点,比如某点的权值是3,我们就当作有3个这个点,然后就是找中间点了

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
struct Node{
	ll pos;
	ll w;
}num[10010];
bool cmp(Node a,Node b){
	return a.pos<b.pos;
}
int main(){
	//freopen("in.txt","r",stdin);
	int n;
	while(cin>>n){
		ll sum=0;
		for(int i=0;i<n;i++){
			scanf("%lld%lld",&num[i].pos,&num[i].w);
			sum+=num[i].w;
		}
		ll res=sum/2;
		sort(num,num+n,cmp);
		ll pos=0;
		Node flag=num[0];
		for(int i=0;i<n;i++){
			pos+=num[i].w;
			if(pos>res){
				flag=num[i];
				break;
			}
		}
		ll ans=0;
		for(int i=0;i<n;i++){
			ans+=abs(num[i].pos-flag.pos)*num[i].w;
		}
		cout<<ans<<endl;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值