zoukankan      html  css  js  c++  java
  • hdu 5073 Galaxy(14鞍山区域赛 D) 二分 + 递推

    题意:给定你一条直线,直线上面有n个点,你可以移动k个点,求所有点到重心距离的平方和最小值为多少。

    解题思路:这里可以知道 保持一段不移动然后把所有的点都移动到这一段的重心才是最优解,那我们很容易想到枚举这一段的端点,但是如果枚举端点,时间复杂度会高达

    n^2,所以我们要知道区间之间的关系,假设 lsum ,rsum  ,lans,rans ,分别为 重心左右的 距离和 和重心左右的平方和,然后每次移动找重心位置,再算 这四个值之间的递推关系就行了。

    解题代码:

      1 // File Name: d.cpp
      2 // Author: darkdream
      3 // Created Time: 2014年10月22日 星期三 13时26分25秒
      4 
      5 #include<vector>
      6 #include<list>
      7 #include<map>
      8 #include<set>
      9 #include<deque>
     10 #include<stack>
     11 #include<bitset>
     12 #include<algorithm>
     13 #include<functional>
     14 #include<numeric>
     15 #include<utility>
     16 #include<sstream>
     17 #include<iostream>
     18 #include<iomanip>
     19 #include<cstdio>
     20 #include<cmath>
     21 #include<cstdlib>
     22 #include<cstring>
     23 #include<ctime>
     24 #define LL long long
     25 #define maxn 51005
     26 #define eps 1e-8
     27 using namespace std;
     28 double a[maxn];
     29 int site[maxn];
     30 double zx[maxn];
     31 int LN;
     32 int find(double x , int l , int r)
     33 {
     34 
     35    while(l <= r )
     36    {
     37       int m = (l +  r)/2;
     38       if(a[m] > x)
     39           r = m - 1; 
     40       else 
     41           l = m + 1;
     42    }
     43    return r; 
     44 }
     45 int main(){
     46     int t; 
     47     scanf("%d",&t);
     48     while(t--)
     49     {
     50         int n , k ; 
     51         scanf("%d %d",&n,&k);
     52         for(int i = 1;i <= n;i ++)
     53         {
     54            scanf("%lf",&a[i]);
     55         }
     56         sort(a+1,a+1+n);
     57         if(k >= n)
     58         {
     59             printf("0.00000000000
    ");
     60             continue;
     61         }
     62         LN = n - k ;
     63         double sum = 0 ; 
     64         double lans,rans,lsum,rsum;
     65         lans = rans = lsum = rsum = 0 ;
     66 
     67         for(int i = 1;i <= LN;i ++)
     68         {
     69             sum += a[i];  
     70         }
     71         zx[1] = sum / LN;
     72         site[1] = find(zx[1],1,1 + LN-1);
     73         for(int i = 1;i <= LN;i ++)
     74         {
     75            double tt = fabs(zx[1] - a[i]);
     76            if(a[i] <= zx[1])
     77            {
     78               lsum += tt;
     79               lans += tt * tt; 
     80            }else {
     81               rsum += tt; 
     82               rans += tt * tt; 
     83            }
     84         }
     85         double mi = lans + rans;
     86         for(int i = 2;i <= k + 1;i ++)
     87         {
     88            sum -= a[i-1];
     89            sum += a[i + LN -1];
     90            zx[i] = sum/LN;
     91            site[i] = find(zx[i],i,i + LN -1);
     92            double dis = zx[i] - zx[i-1] ;
     93            lsum  -= fabs(a[i-1] - zx[i-1]);
     94            lans  -= fabs(zx[i-1] -a[i-1]) * fabs(zx[i-1] -a[i-1]);
     95            lans  += lsum * dis * 2 + dis *dis * (site[i-1] - i + 1);
     96            lsum += dis * (site[i-1] - i + 1);
     97            for(int j = site[i-1] + 1;j <= site[i];j ++)
     98            {
     99                 double tt = fabs(a[j] - zx[i]);
    100                 double tt1 = fabs(a[j] - zx[i-1]);
    101                 lsum += tt; 
    102                 lans += tt*tt;
    103                 rsum -= tt1;
    104                 rans -= tt1 * tt1;
    105            }
    106           // printf("%lf
    ",rsum);
    107            rans += dis * dis *(i-1 + LN - 1 - site[i]) - rsum * dis * 2;
    108            rans += fabs(zx[i] - a[i+LN-1]) * fabs(zx[i] - a[i+LN-1]) ;
    109            rsum += fabs(zx[i] - a[i+LN-1]) - dis *(i-1+LN-1-site[i]);
    110            //printf("%lf
    ",rsum);
    111            //printf("%lf %lf %lf %lf %lf
    ",lsum,rsum,lans,rans,zx[i]);
    112            if(rans + lans < mi)
    113                mi = rans + lans;
    114         }
    115      printf("%.10lf
    ",mi);
    116         
    117     }
    118 return 0;
    119 }
    View Code
    没有梦想,何谈远方
  • 相关阅读:
    VisionPro 各控件的C#中类库 CogAcqFifoTool(2)
    VisionPro 各控件的C#中类库 CogAcqFifoTool(1)
    C# new的三种用法
    C# as用法
    C# 基类之Environment类
    C#开发的软件在Windows7中出现对路径的访问被拒绝异常
    IDEA创建springboot项目【mas-service】
    .Net Core-ObjectPool
    中介者模式的实现-MediatR
    .NET Core分布式事件总线、分布式事务解决方案:CAP
  • 原文地址:https://www.cnblogs.com/zyue/p/4044112.html
Copyright © 2011-2022 走看看