PIPIOJ 1413:兵士小隊Ⅲ加重中央値問題

http://pipioj.online/problem.php?id=1413
ここに画像の説明を挿入します
アイデア:加重中央値問題詳細な証拠については、Baidu百科事典を参照してください最初に結論を出します。∑ i = 1 n ∣ xi − x ∣ ∗ wi \ sum_ {i = 1} ^ {n} | x_i-x | * w_ii = 1n個xx wx = x(∑ i = 1 nwi)/ 2 x = x _ {(\ sum_ {i = 1} ^ nw_i)/ 2}の場合の最小値バツ=バツi = 1n個w/ 2(ここでは添え字の問題を慎重に検討していません)。これが私自身の理解です(厳密ではない証明)。∑ i = 1 n ∣ xi − x ∣ \ sum_ {i = 1} ^ {n} | x_i-x |i = 1n個x最小値X |場合にのみ、X = XN / 2×= X_ {N / 2}バツ=バツN / 2(つまり、xが中央値に等しい場合)、上記の式では、nnから数列をとることができます。n個のアイテムが∑ i = 1 nwi \ sum_ {i = 1} ^ nw_iに展開されますi = 1n個wこのようにして、重みを取り除くことができ、問題は一般的な中央値の問題に変換され、結論は依然として有効です。

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
using ll=long long;

const int maxn=1e5+5;

struct node
{
    
    
    int x,y,w;
    node(int x=0,int y=0,int w=0):x(x),y(y),w(w){
    
    }
};

int n;
node a[maxn];

int main()
{
    
    
    scanf("%d",&n);
    int num=0;
    for(int i=1;i<=n;i++)
        scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].w),num+=a[i].w;
    num=(num+1)>>1;
    sort(a+1,a+1+n,[](const node &a,const node &b){
    
     return a.x<b.x; });
    ll ans=0;
    int tmp=0,idx=0,mid;
    while(tmp<num)
        tmp+=a[++idx].w;
    mid=a[idx].x;
    for(int i=1;i<=n;i++)
        ans+=(ll)abs(a[i].x-mid)*a[i].w;
    sort(a+1,a+1+n,[](const node &a,const node &b){
    
     return a.y<b.y; });
    tmp=idx=0;
    while(tmp<num)
        tmp+=a[++idx].w;
    mid=a[idx].y;
    for(int i=1;i<=n;i++)
        ans+=(ll)abs(a[i].y-mid)*a[i].w;
    printf("%lld\n",ans);
    return 0;
}


おすすめ

転載: blog.csdn.net/xiji333/article/details/114448408