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
输出最小的带权距离之和。
Input示例
5 -1 1 -3 1 0 1 7 1 9 1
Output示例
20
中位数的题目,但我是用前缀和做的,从小到大排列,也可以证明在中间时最小
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <stack> #include <cstdlib> #include <iomanip> #include <cmath> #include <cassert> #include <ctime> #include <map> #include <set> using namespace std; #pragma comment(linker, "/stck:1024000000,1024000000") #pragma GCC diagnostic error "-std=c++11" #define lowbit(x) (x&(-x)) #define max(x,y) (x>=y?x:y) #define min(x,y) (x<=y?x:y) #define MAX 100000000000000000 #define MOD 1000000007 #define esp 1e-9 #define pi acos(-1.0) #define ei exp(1) #define PI 3.1415926535897932384626433832 #define ios() ios::sync_with_stdio(true) #define INF 0x3f3f3f3f typedef long long ll; struct node { ll x,w; bool operator<(const node &a) const{ return a.x>x; } }e[10006]; int n; ll sum_front[10006],sum_last[10006],l[10006],r[10006]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld%lld",&e[i].x,&e[i].w); sort(e+1,e+n+1); for(int i=1;i<=n;i++) { sum_front[i]=sum_front[i-1]+l[i-1]*(e[i].x-e[i-1].x); l[i]=l[i-1]+e[i].w; } for(int i=n;i;i--) { sum_last[i]=sum_last[i+1]+r[i+1]*(e[i+1].x-e[i].x); r[i]=r[i+1]+e[i].w; } ll ans=1000000000000000000; for(int i=1;i<=n;i++) ans=min(ans,sum_front[i]+sum_last[i]); printf("%lld\n",ans); return 0; }