51NOD 1110 距离之和最小 V3(中位数 + 技巧)

传送门

X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[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

解题思路:

因为最后要乘以权值w[i],那么我们可以想象成有w[i]个x[i]坐标组成的,那么我们又转化为中位数的问题了,首先我们将统计有多少个数(也就是把所有的权值相加),然后除以2,然后按照从小到大排序,找最中间那个数,找到记录那个点的坐标x[i],然后剩下的就简单了,按照题目意思做就行了。

My Code:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long LL;
const int MAXN = 1e4+5;
struct node
{
    LL x, w;
} a[MAXN];
bool cmp(node a, node b)
{
    return a.x < b.x;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        LL sum = 0;
        for(int i=0; i<n; i++)
        {
            scanf("%I64d%I64d",&a[i].x,&a[i].w);
            sum += a[i].w;
        }
        sum>>=1;
        sort(a, a+n, cmp);
        LL ans = 0, tmp = a[0].x;
        for(int i=0; i<n; i++)
        {
            ans += a[i].w;
            if(ans > sum)
            {
                tmp = a[i].x;
                break;
            }
        }
        LL ret = 0;
        for(int i=0; i<n; i++)
            ret += abs(a[i].x-tmp)*a[i].w;
        printf("%I64d\n",ret);
    }
    return 0;
}

时间: 2024-10-14 14:48:30

51NOD 1110 距离之和最小 V3(中位数 + 技巧)的相关文章

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 &

51nod 1110 距离之和最小V3

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 输出最小的带权距离之

1110 距离之和最小 V3

1110 距离之和最小 V3 基准时间限制:1 秒 空间限制:131072 KB X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].该点到其他点的带权距离 = 实际距离 * 权值.求X轴上一点使它到这N个点的带权距离之和最小,输出这个最小的带权距离之和. Input 第1行:点的数量N.(2 <= N <= 10000) 第2 - N + 1行:每行2个数,中间用空格分隔,分别是点的位置及权值.(-10^5 <= X[i] <= 10^5,1 <= 

51NOD 1108 距离之和最小 V2(中位数 + 化整为分)

传送门 三维空间上有N个点, 求一个点使它到这N个点的曼哈顿距离之和最小,输出这个最小的距离之和. 点(x1,y1,z1)到(x2,y2,z2)的曼哈顿距离就是|x1-x2| + |y1-y2| + |z1-z2|.即3维坐标差的绝对值之和. Input 第1行:点的数量N.(2 <= N <= 10000) 第2 - N + 1行:每行3个整数,中间用空格分隔,表示点的位置.(-10^9 <= X[i], Y[i], Z[i] <= 10^9) Output 输出最小曼哈顿距离之

51nod 1096 距离之和最小【中位数】

1096 距离之和最小 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 X轴上有N个点,求X轴上一点使它到这N个点的距离之和最小,输出这个最小的距离之和. Input 第1行:点的数量N.(2 <= N <= 10000) 第2 - N + 1行:点的位置.(-10^9 <= P[i] <= 10^9) Output 输出最小距离之和 Input示例 5 -1 -3 0 7 9 Output示例 20[分析]:注意LL,距离abs

51nod1110 距离之和最小 V3

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 X轴上有N个点,每个点除了包括一个位置数据X[i],还包括一个权值W[i].该点到其他点的带权距离 = 实际距离 * 权值.求X轴上一点使它到这N个点的带权距离之和最小,输出这个最小的带权距离之和. Input 第1行:点的数量N.(2 <= N <= 10000) 第2 - N + 1行:每行2个数,中间用空格分隔,分别是点的位置及权值.(-10^5 <= X[i] <= 10^5,1 <= W[i] <

【51NOD】1096 距离之和最小

[算法]数学 [题解] 其实就是求中位数,奇数个点就是最中间的点,偶数个点就是最中间两个点和它们之间的区域皆可(所以偶数不必取到两点正中央,取两点任意一点即可). 我们可以想象现在x轴上有n个点,我们设定的目标点在最左边,那么可以算出距离总和ans. 目标点往右移动1,相当于ans+左边点数-右边点数. 那么目标点到达正中央(或中央两点之间)前,ans单调递减(左边点<右边点),之后ans又单调递增(左边点>右边点) 由此,目标点为中位数点时,距离之和最小. #include<cstdi

1108 距离之和最小V2

1108 距离之和最小 V2 三维空间上有N个点, 求一个点使它到这N个点的曼哈顿距离之和最小,输出这个最小的距离之和. 点(x1,y1,z1)到(x2,y2,z2)的曼哈顿距离就是|x1-x2| + |y1-y2| + |z1-z2|.即3维坐标差的绝对值之和. Input 第1行:点的数量N.(2 <= N <= 10000) 第2 - N + 1行:每行3个整数,中间用空格分隔,表示点的位置.(-10^9 <= X[i], Y[i], Z[i] <= 10^9) Output

HDU 1227 dp距离和最小,中位数的应用

在n个商店中建m个仓库,使各个商店到仓库的路程之和最小,商店到哪个仓库是有选择的, 总之路程之和要最小! 思路: 从第i个商店到第j个商店建一个仓库,这个仓库所建的位置一定是dis[(i+j)/2],即建在它的中位数处, 所以,这个增加值就是case[i][j]=abs(dis[k]-dis[(i+j)/2])(i<=k<=j); 我们要把它初始为一个尽可能大的数,要找dp[i][j],首先dp[i][j]=10000000(尽可能的大):然后找前一个状态,dp[i-1][m] 为啥是m呢?因