51NOD 1110 距离之和最小 V3 三分法

来源:互联网 发布:java获取软件版本号 编辑:程序博客网 时间:2024/06/04 19:26
1110 距离之和最小 V3基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏  关注X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i]。该点到其他点的带权距离 = 实际距离 * 权值。求X轴上一点使它到这N个点的带权距离之和最小,输出这个最小的带权距离之和。Input1行:点的数量N。(2 <= N <= 10000)第2 - N + 1行:每行2个数,中间用空格分隔,分别是点的位置及权值。(-10^5 <= X[i] <= 10^51 <= W[i] <= 10^5)Output输出最小的带权距离之和。Input示例5-1 1-3 10 17 19 1Output示例20

#include<iostream>#include<stdlib.h>#include<stdio.h>#include<string>#include<vector>#include<deque>#include<queue>#include<algorithm>#include<set>#include<map>#include<stack>#include<time.h>#include<math.h>#include<list>#include<cstring>#include<fstream>//#include<memory.h>using namespace std;#define ll long long#define ull unsigned long long#define pii pair<int,int>#define INF 1000000007#define pll pair<ll,ll>#define pid pair<int,double>const int N = 10000 + 5;int x[N];int w[N];ll dis_sum(int d,int n){    ll ans=0;    for(int i=0;i<n;++i){        ans+=(ll)abs((x[i]-d))*w[i];    }    return ans;}ll slove(int l,int r,int n){    ll ans = 1e17;    while(r-l>2){        int t = (r-l)/3;        ll dis1=dis_sum(l+t,n),                dis2=dis_sum(r-t,n);        if(dis1<dis2){            r-=t;        }        else{            l+=t;        }        ans = min(ans,min(dis1,dis2));    }    return ans;}int main(){    //freopen("/home/lu/文档/r.txt","r",stdin);    //freopen("/home/lu/文档/w.txt","w",stdout);    int n;    scanf("%d",&n);    int l=INF,r=-INF;    for(int i=0;i<n;++i){        scanf("%d%d",x+i,w+i);        l=min(l,x[i]);        r=max(r,x[i]);    }    printf("%lld\n",slove(l,r,n));    return 0;}
0 0
原创粉丝点击