hdu 5037 Galaxy 鞍山现场赛题目
2014-10-24 08:46
253 查看
现场赛卡死的一道题,居然不会维护前缀和,实在是太菜了。
题目大意: 给你N个星球,你可以拿走K个星球放到任意的位置上去,星球都在x轴上,星球的质量都为1,求各个星球到质心的方差最小值。
证明1:拿走K个星球,剩下N-K个星球,将K个星球放到剩余星系的质心上方差最小。
定理:对v个星球,他们的质心为方差最小的位置,如果发生改变方差会变大.
ave = (x1+.....+xv)/v;假设不在质心上,那么假设放在ave+y(y可正可负).
sum (xi-ave-y)^2 = sum(xi-ave)^2//放在质心的方差
+sum(y^2)//一定大于0
+sum(2*(xi-ave)y)// sum(xi-ave) = sum(xi)-ave*v = 0
得证
证明2:一定是从两端拿走星球使得方差最小,那么拿走剩下的一定是连续的
对于三个点x1 < x2 < x3.他们的质心一定在x1 和 x3 之间,如果我拿走x2,假设质心在x2 与 x3 之间的情况,那么一定拿走x1会使得方差更小。反之如果在x1 x2之间的话,同理拿走x3更小,所以一定是拿走两端的点使得方差最小。
错证:从两端拿走拿走到当前质心最远的点。当时比赛就是这么做的,当时没能证明出来,事实上是错的,这种策略局部最优不表示整体最优,错误数据如
input
1
5 3
1 2 3 100 100
output
0
然后比赛就跪了
所以只需要在前两个贪心的基础上,维护两个前缀和就可以解决了.
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
double a[50005];
double sum,s;
bool cmp (double a,double b){
return a < b;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int num,K;
sum = 0;s = 0;
scanf("%d%d",&num,&K);
int N = num - K;
double ans = 0;
for(int i=0;i<num;i++){
scanf("%lf",&a[i]);
}
sort(a,a+num,cmp);
if(K+1>=num)printf("%.10f\n",0.0);
else{
for(int i=0;i<N;i++){
sum+=a[i];
s+=a[i]*a[i];
}
ans = s-double(sum*sum/N);
for(int i=N;i<num;i++){
s = s - a[i-N]*a[i-N]+a[i]*a[i];
sum = sum - a[i-N] + a[i];
double tem = s-double(sum*sum/N);
ans = min(ans,tem);
}
printf("%.10f\n",ans);
}
}
}
题目大意: 给你N个星球,你可以拿走K个星球放到任意的位置上去,星球都在x轴上,星球的质量都为1,求各个星球到质心的方差最小值。
证明1:拿走K个星球,剩下N-K个星球,将K个星球放到剩余星系的质心上方差最小。
定理:对v个星球,他们的质心为方差最小的位置,如果发生改变方差会变大.
ave = (x1+.....+xv)/v;假设不在质心上,那么假设放在ave+y(y可正可负).
sum (xi-ave-y)^2 = sum(xi-ave)^2//放在质心的方差
+sum(y^2)//一定大于0
+sum(2*(xi-ave)y)// sum(xi-ave) = sum(xi)-ave*v = 0
得证
证明2:一定是从两端拿走星球使得方差最小,那么拿走剩下的一定是连续的
对于三个点x1 < x2 < x3.他们的质心一定在x1 和 x3 之间,如果我拿走x2,假设质心在x2 与 x3 之间的情况,那么一定拿走x1会使得方差更小。反之如果在x1 x2之间的话,同理拿走x3更小,所以一定是拿走两端的点使得方差最小。
错证:从两端拿走拿走到当前质心最远的点。当时比赛就是这么做的,当时没能证明出来,事实上是错的,这种策略局部最优不表示整体最优,错误数据如
input
1
5 3
1 2 3 100 100
output
0
然后比赛就跪了
所以只需要在前两个贪心的基础上,维护两个前缀和就可以解决了.
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
double a[50005];
double sum,s;
bool cmp (double a,double b){
return a < b;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int num,K;
sum = 0;s = 0;
scanf("%d%d",&num,&K);
int N = num - K;
double ans = 0;
for(int i=0;i<num;i++){
scanf("%lf",&a[i]);
}
sort(a,a+num,cmp);
if(K+1>=num)printf("%.10f\n",0.0);
else{
for(int i=0;i<N;i++){
sum+=a[i];
s+=a[i]*a[i];
}
ans = s-double(sum*sum/N);
for(int i=N;i<num;i++){
s = s - a[i-N]*a[i-N]+a[i]*a[i];
sum = sum - a[i-N] + a[i];
double tem = s-double(sum*sum/N);
ans = min(ans,tem);
}
printf("%.10f\n",ans);
}
}
}
相关文章推荐
- 【数学,方差运用,暴力求解】hdu-5037 Galaxy (2014鞍山现场)
- hdu 5073 Galaxy(2014 鞍山现场赛)
- HDU 5073 Galaxy (2014鞍山现场赛D题)
- hdu 5073 Galaxy(2014 鞍山现场赛)
- ACM/ICPM2014鞍山现场赛D Galaxy (HDU 5073)
- HDU 5073 Galaxy (2014 ACM/ICPC 鞍山赛区现场赛D题)
- ACM/ICPM2014鞍山现场赛D Galaxy (HDU 5073)
- hdu 5073 Galaxy /2014鞍山现场赛D题
- hdu 5073 Galaxy (鞍山现场赛D题)
- hdu 5037 Galaxy 2014鞍山区域赛D(最小方差 贪心 想法)
- HDU 5073 Galaxy(2014鞍山赛区现场赛D题)
- hdu 5073 Galaxy(2014acm鞍山亚洲分部 D)
- hdu 5071 Chat /2014鞍山现场赛B题 (模拟)
- hdu 5078 2014鞍山现场赛 水题
- HDU 5074 Hatsune Miku(2014鞍山赛区现场赛E题)
- hdu 2014鞍山赛区 5073 Galaxy
- hdu 5078(2014鞍山现场赛 I题)
- HDU 5071 Chat (2014ICPC鞍山赛区现场赛B题)
- 2014ACM/ICPC亚洲区鞍山赛区现场赛D Galaxy(hdu 5073)
- hdu 5071(2014鞍山现场赛B题,大模拟)