距离之和最小 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
 
  
解题思路:对于本题我们需要确定的一点是最优的点的位置肯定是这个N个点中其中的一个,我们可以利用反证法来证明我们的猜想是正确的。
假设我们的最优解在第j和第j+1个顶点之间,则左边存在j-1个顶点,右边存在n-j-1个顶点,我们分下面三种情况讨论:
(1)j-1=n-j-1时,我们将最优点放到第j个点或者第j+1个点得到的最终结果都要比放在j和j+1之间要优
(2)j-1>n-j-1时,我们将最优点放在第j个点要比放在j和j+1之间更优
(3)j-1<n-j-1时,我们将最优点放在第j+1点要比放在j和j+1之间更优。
上面的东西搞明白了,我们便可以dp了,dp[i]表示以i为放置点得到的结果,然后ans = min(dp[i]) (1<=i<=n)
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
const int maxn = 10010;

struct Point {
    int x, w;
    Point() { }
    Point(int t_x, int t_w) : x(t_x), w(t_w) { }
    bool operator < (const Point &p) const {
        return x < p.x;
    }
}point[maxn];

ll dp1[maxn], dp2[maxn], dp[maxn];
ll sumw1[maxn], sumw2[maxn];

int main() {

    //freopen("aa.in", "r", stdin);

    ll ans;
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) {
        scanf("%d %d", &point[i].x, &point[i].w);
    }
    sort(point + 1, point + n + 1);
    sumw1[0] = 0;
    dp1[1] = 0;
    for(int i = 1; i <= n; ++i) {
        if(i > 1) {
            dp1[i] = dp1[i-1] + sumw1[i-1] * (point[i].x - point[i-1].x);
        }
        sumw1[i] = sumw1[i-1] + point[i].w;
    }
    sumw2[n+1] = 0;
    dp2[n] = 0;
    for(int i = n; i >= 1; --i) {
        if(i < n) {
            dp2[i] = dp2[i+1] + sumw2[i+1] * (point[i+1].x - point[i].x);
        }
        sumw2[i] = sumw2[i+1] + point[i].w;
    }
    dp[1] = dp1[1] + dp2[1];
    ans = dp[1];
    for(int i = 2; i <= n; ++i) {
        dp[i] = dp1[i] + dp2[i];
        if(dp[i] < ans) {
            ans = dp[i];
        }
    }
    printf("%lld\n", ans);
    return 0;
}

另外本题还有其余的解法,参考博客:http://blog.csdn.net/zhang20072844/article/details/13372753
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
const int maxn = 10010;

struct Point {
    int x, w;
    Point() { }
    Point(int t_x, int t_w) : x(t_x), w(t_w) { }
    bool operator < (const Point &p) const {
        return x < p.x;
    }
}point[maxn];

int main() {

    int n;
    int pos;
    ll sumw = 0, tw = 0, ans = 0;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i) {
        scanf("%d %d", &point[i].x, &point[i].w);
        sumw += point[i].w;
    }
    sort(point, point + n);
    for(int i = 0; i < n; ++i) {
        tw += point[i].w;
        if(tw >= sumw/2) {
            pos = i;
            break;
        }
    }
    for(int i = 0; i < n; ++i) {
        if(i < pos) {
            ans += 1LL * (point[pos].x - point[i].x) * point[i].w;
        } else if(pos < i) {
            ans += 1LL * (point[i].x - point[pos].x) * point[i].w;
        }
    }
    printf("%lld\n", ans);
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
方位距离跟踪是目标跟踪中的一种方法,它利用最小二乘法完成对目标位置的估计。在观测系统中,目标通过观测站(如雷达、声纳等传感器)进行观测,并使用坐标系(如二维、三维直角坐标系、极坐标系、球坐标系)来描述目标的位置。在跟踪过程中,目标的位置信息通过数据关联方法(如近邻、聚类、联合概率关联)进行分类,然后利用最小二乘法进行位置估计。此外,为了消除噪声,还可以使用滤波算法(如卡尔曼滤波、粒子滤波)进行状态估计,从而对目标参数进行估计。最后,跟踪维持是指在目标移动过程中,通过继承数据来保持目标的跟踪。\[1\]\[2\] #### 引用[.reference_title] - *1* *2* [目标定位跟踪系统概述](https://blog.csdn.net/qq_54813519/article/details/128245478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [在无线传感器网络中对目标的跟踪——基于KF和MLE(最大似然估计)结合的距离测量](https://blog.csdn.net/xie1151001142/article/details/52836314)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值