题意:

\(x\)轴上有\(n\)个质量为\(1\)的点,他们的坐标分别为\(x_i\).

质心的坐标为\(\frac{\sum{x_i}} {n}\)

转动惯量为\(\sum{d_i^2}\),其中\(d_i\)为第\(i\)个点到质心的距离.

现在你可以至多移动其中的\(k\)个点,求可能的最小的转动惯量.

分析:

首先可以任意移动其中的\(k\)个点,我们可以选择直接将他们移动到质心的位置使得转动惯量为\(0\).

所以这就相当于删去了\(k\)个点,选剩下的\(n-k\)个点.

还有一个直观的感受是选的点越集中整体的转动惯量越小,所以我们一定要选连续的\(n-k\)个点.

所以就移动长为\(n-k\)的区间,维护一个所有区间的转动惯量的最小值.

在区间移动的过程中,质心也会跟着移动.

在移动的过程中,质心远离了一些点,质心跨过了一些点(即从这些点的左边移动到了右边),质心也靠近了一些点.

所以我们可以将这些点分成左中右三个部分.

  • 对于左边的点来说,转动惯量一直是增大的,而且增量为\((x+ \Delta x)^2-x^2\),化简为\(2x \Delta x+{ \Delta x}^2\).再进行一次求和得到\(2 \sum{x} \Delta x + cnt {\Delta x}^2\),其中\(cnt\)为远离的那些点的个数
  • 对于中间的点,我们就直接计算转动惯量的增量即可.在质心移动的过程中每个点最多被跨过一次,所以这里的复杂度是\(O(n)\)的
  • 对于右边的点来说,转动惯量是一直减小的,减小的量为\(x^2 - (x - \Delta x)^2\),化简为\(2x \Delta x - { \Delta x}^2\).进行求和:\(2 \sum{x} \Delta x - cnt {\Delta x}^2\),其中\(cnt\)为靠近的那些点的个数

上式中的\(\sum{x}\)可以预处理前缀和\(pre\)计算出来.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 50000 + 10;
int n, k;
double x[maxn]; double pre[maxn]; inline double Sum(int i, int j) {
return pre[j] - pre[i - 1];
} int main()
{
//freopen("in.txt", "r", stdin); int T; scanf("%d",&T); while(T--) {
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; i++) scanf("%lf", x + i);
sort(x + 1, x + n + 1);
pre[1] = x[1];
for(int i = 2; i <= n; i++) pre[i] = pre[i - 1] + x[i]; double sum = 0, ans;
for(int i = 1; i <= n - k; i++) sum += x[i];
double center = sum / (n - k);
double inertia = 0;
for(int i = 1; i <= n - k; i++) inertia += (x[i] - center) * (x[i] - center);
ans = inertia;
int border = 0;
while(x[border + 1] <= center) border++; for(int s = 2; s <= k + 1; s++) {
int t = s + n - k - 1;
double next_center = center + (x[t] - x[s - 1]) / (n - k);
int next_border = border;
while(next_border < n && x[next_border + 1] <= next_center) next_border++;
double delta = next_center - center; double next_inertia = inertia;
next_inertia -= (x[s-1]-center) * (x[s-1]-center);
next_inertia += (x[t]-center) * (x[t]-center);
int lft = border - s + 1, rgh = t - next_border;
double sigl = center * lft - Sum(s, border);
double sigr = Sum(next_border + 1, t) - center * rgh;
next_inertia += 2 * delta * sigl + lft * delta * delta;
next_inertia -= 2 * delta * sigr - rgh * delta * delta;
for(int i = border + 1; i <= next_border; i++)
next_inertia += (x[i]-next_center)*(x[i]-next_center) - (x[i]-center)*(x[i]-center);
ans = min(ans, next_inertia); center = next_center;
border = next_border;
inertia = next_inertia;
} printf("%.10f\n", ans);
} return 0;
}

LA 7049 Galaxy 枚举的更多相关文章

  1. LA 3695 部分枚举

    运用部分枚举的思想,很明显完全枚举点的思想是不可能的.改为枚举上下边界,当确定右边界j后,对左边界i,可以有点数为on[j]+on[i]+(leftu[j]-leftu[i])+leftd[j]-le ...

  2. LA 3695 Distant Galaxy

    给出n个点的坐标(坐标均为正数),求最多有多少点能同在一个矩形的边界上. 题解里是构造了这样的几个数组,图中表示的很明白了. 首先枚举两条水平线,然后left[i]表示竖线i左边位于水平线上的点,on ...

  3. LA 2402 (枚举) Fishnet

    题意: 正方形四个边界上分别有n个点,将其划分为(n+1)2个四边形,求四边形面积的最大值. 分析: 因为n的规模很小,所以可以二重循环枚举求最大值. 求直线(a, 0) (b, 0) 和直线(0, ...

  4. UVa LA 3695 - Distant Galaxy 前缀和,状态拆分,动态规划 难度: 2

    题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  5. LA 4253 箭术(二分枚举)

    https://vjudge.net/problem/UVALive-4253 题意: 有n个平行于x轴的线段,每条线段代表一个靶子.判断是否可以站在x轴上[0,W]区间内的某个位置射箭. 思路:二分 ...

  6. LA 4794 状态DP+子集枚举

    状态压缩DP,把切割出的面积做状态压缩,统计出某状态下面积和. 设f(x,y,S)为在状态为S下在矩形x,y是否存在可能划分出S包含的面积.若S0是S的子集,对矩形x,y横切中竖切,对竖切若f(x,k ...

  7. LA 3887 - Slim Span 枚举+MST

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  8. LA 3602 - DNA Consensus String 枚举

    原题地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  9. LA 3602 DNA Consensus String (暴力枚举)

    题意:给定m个长度为n的DNA序列,求一个最短的DNA序列,使得总Hamming距离最小. Hamming距离等于字符不同的位置个数. 析:看到这个题,我的第一感觉是算时间复杂度,好小,没事,完全可以 ...

随机推荐

  1. 关于 SQL Server Reporting Services 匿名登录的解决方案

    每次访问报表都需要windows验证,这样的报表给客户确实很说不过去. SSRS 可以匿名登录的设定步骤: 环境: 开发工具:SQL Server Business Intelligence Deve ...

  2. go日志输入到es

    1.依赖 github.com/alecthomas/log4go 2.配置 <filter enabled="true"><!-- enabled=false ...

  3. 基于JavaMail的Java邮件发送:复杂邮件发送

    参考:http://blog.csdn.net/xietansheng/article/details/51722660package com.bfd.ftp.utils;import java.ut ...

  4. 帝国empirecms后台登陆次数限制修改

    打开文件:\e\config\config.php, 找到 'loginnum'=>5, 把5改为自己想要的数字即可

  5. keil下JLINK在线调试仿真设置,SWD连接

    keil下JLINK在线调试仿真设置,以下三个步骤搞定: 有时我们编译时会遇到空间不足的情况,首先我们应该把 flash和RAM的size 设置为当前所用芯片的大小,如下我使用了一个片上flash 2 ...

  6. reactnative资源

    http://facebook.github.io/react-native/docs/getting-started.html

  7. SqlServer中生成一串连续数字

    在SQLServer中一串连续数字,如1,2,3,4,5,....或者 1 2 3 4 5 没有现成方法,网上都用通用表表达式递归生成.今天想到一个还算简单的方法,记录下来: select row_n ...

  8. HDU 2639 Bone Collector II (01背包,第k解)

    题意: 数据是常规的01背包,但是求的不是最大容量限制下的最佳解,而是第k佳解. 思路: 有两种解法: 1)网上普遍用的O(V*K*N). 2)先用常规01背包的方法求出背包容量限制下能装的最大价值m ...

  9. 问题驱动的Git学习

    (搬运自我在SegmentFault的博客) 本人是个Git新手,平时用Git最多的就是push,因为别的都不怎么会用.这几天因为在小组中负责代码的整合,顺便将代码提交到Github,接触到了Git更 ...

  10. Round #322 (Div. 2) 581D Three Logos (模拟)

    先枚举两个矩形,每个矩形横着放或竖着放,把一边拼起来, 如果不是拼起来有缺口就尝试用第三个矩形去补. 如果没有缺口就横着竖着枚举一下第三个矩形和合并的矩形x或y拼接. #include<bits ...