sgu 114 三分

来源:互联网 发布:淘宝办公室装修方案 编辑:程序博客网 时间:2024/05/01 12:28

题意: 在一条直线上 到每个点pi 个人,位置xi 。 建一个中转站 ,每个位置上的 不高兴 的值 就是 pi*( xi  - X)   ,X 为 中转站。问不高兴的值的总和最小是多少。

对一个位置 向两边的变化速率的分析的。  一个点向右的速率是  左侧人数和 减去 右侧人数和。随着点从左端向右端移动的过程中 速率由负值一直增大, 则总和的变化就是 下凸曲线,就是三分曲线。


#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <stack>#include <cstring>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>#include <assert.h>#include <queue>#define REP(i,n) for(int i=0;i<n;i++)#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)#define ALLL(x) x.begin(),x.end()#define SORT(x) sort(ALLL(x))#define CLEAR(x) memset(x,0,sizeof(x))#define FILLL(x,c) memset(x,c,sizeof(x))using namespace std;const double eps = 1e-9;#define LL long long #define pb push_backconst int maxn  = 110000;int   x[maxn], p[maxn];int n;int l,r;double f(double a){double ans = 0 ;    for(int i=1;i<=n;i++){     ans +=   fabs(a-x[i])*p[i];    }    return ans; }void solve(){    double left = l;     double right = r;    while(right - left >1e-9){      double lmid = (left +right )/2;      double rmid = (lmid + right)/2;      if(f(lmid)> f(rmid)){       left = lmid ;      }else{       right =rmid;      }    }    printf("%.5f\n",left);  //  cout <<f(3)<<endl;  //  cout << f(2)<<endl;}int main(){   while(~scanf("%d",&n)){      for(int i=1;i<=n;i++){         scanf("%d%d",&x[i],&p[i]);         if(i==1){           l =r = x[i];         }else{            l = min(x[i],l);            r = max(x[i],r);         }      }      solve();   }    return 0;}


原创粉丝点击