51nod 1098 最小方差 排序+前缀和+期望方差公式
题目:
题目要我们,在m个数中,选取n个数,求出这n个数的方差,求方差的最小值。
1.我们知道,方差是描述稳定程度的,所以肯定是着n个数越密集,方差越小。
所以我们给这m个数排个序,从连续的n个数中找。
2.方差公式D(x^2) = E(x^2)- E(x)^2;
E(x) = x*f(x) dx (从负无穷到正无穷积分)
E (x^2) = x^2*f(x) dx (从负无穷到正无穷积分)
3.对于这道题,相当于每个数的权值相同,也就是f(x)相同,都等于1/n。(可以理解f(x)表示概率)
4.我们可以用前缀和来减少时间复杂度。
sum1[i]表示前 i 项的和,方便算出E(x)^2
sum2[i]表示前 i 项平方和 ,方便算出E(x^2)
当我们要算第 i 项到第 j 项共 j-i+1 项的方差的时候我们只用这样写:
ll k1 = sum1[j]-sum1[i-]; // 第i项到第j项的和
double s1 = 1.0*k1/n*k1/n; // k1/n表示平均数E(x), s1表示E(x)^2
ll k2 = sum2[j]-sum2[i-]; // 第i项到第j项的平方和
double s2 = 1.0*k2/n; // s2 和 k2/n 表示E(x^2)
第 i 项到第 j 项的方差就等于 s2-s1 了。
5.我们可以得到大致代码,当然现在就可以直接开始敲了,如果看懂了的话。
double mn = 2e18;
for(int i = n;i <= m; i++){
ll k1 = sum1[i]-sum1[i-n];
double s1 = 1.0*k1/n*k1/n;
ll k2 = sum2[i]-sum2[i-n];
double s2 = 1.0*k2/n; mn = min(s2-s1,mn);
}
6.我们要注意一下精度问题,我的做法是给mn += 1e-8。
代码:
#include <bits\stdc++.h>
using namespace std;
typedef long long ll; int a[];
ll sum1[]; //sum1[i]表示前i项和
ll sum2[]; //sum2[i]表示前i项平方和
int main() {
ll m,n;
cin >> m >> n;
for(int i = ;i <= m; i++){
cin >> a[i];
} sort(a+,a++m); // 排个序,让数字变得紧凑
for(int i = ;i <= m; i++){
sum1[i] = sum1[i-] + a[i];
sum2[i] = sum2[i-] + a[i]*a[i];
} double mn = 2e18; //存最小的方差
for(int i = n;i <= m; i++){
ll k1 = sum1[i]-sum1[i-n]; // 第 i-n+1 项到第 i项共 n 项的和。
double s1 = 1.0*k1/n*k1/n; // k1/n表示平均数E(x),s1表示 E(x)^2
ll k2 = sum2[i]-sum2[i-n]; // 第 i-n+1 项到第 i项共 n 项的和。
double s2 = 1.0*k2/n; // k2/n表示E(x^2) mn = min(s2-s1,mn);
} // 如果不加这个可能会出问题,因为cout double用的是科学记数法,需要消除误差。
mn += 1e-;
cout << (ll)(mn*n) << endl;
return ;
}
// writen by zhangjiuding
51nod 1098 最小方差 排序+前缀和+期望方差公式的更多相关文章
- 51Nod 1098 最小方差 (数论)
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; ty ...
- 51nod 1098 最小方差
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; ty ...
- 51nod 1065 最小正子段和
题目链接:51nod 1065 最小正子段和 房教说用前缀和做,然后看了别人博客懂了后就感觉,这个真有意思... #include<cstdio> #include<cstring& ...
- java算法----排序----(6)希尔排序(最小增量排序)
package log; public class Test4 { /** * java算法---希尔排序(最小增量排序) * * @param args */ public static void ...
- 51nod 1065 最小正字段和 解决办法:set存前缀和,二分插入和二分查找
题目: 这题要求大于0的最小字段和,常规O(n)求最大字段和的方法肯定是没法解的. 我的解法是:用sum[i]存前i项的和,也就是前缀和. 这题就变成了求sum[j]-sum[i]的大于0的最小值( ...
- 51nod 1065 最小正子段和 (贪心)
题目:传送门. 题意:中文题. 题解:求前缀和,并且标记每个数的下标,按照前缀和大小进行从小到大排序.随后进行遍历,如果满足下标data[i-1].id<data[i].id&& ...
- 51nod 1510 最小化序列 | DP 贪心
题目描述 现在有一个长度为n的数组A,另外还有一个整数k.数组下标从1开始. 现在你需要把数组的顺序重新排列一下使得下面这个的式子的值尽可能小. ∑|A[i]−A[i+k]| 特别的,你也可以不对数组 ...
- 51nod 1682 中位数计数(前缀和)
51nod 1682 中位数计数 思路: sum[i]表示到i为止的前缀和(比a[i]小的记为-1,相等的记为0,比a[i]大的记为1,然后求这些-1,0,1的前缀和): hash[sum[i]+N] ...
- 51nod 1283 最小周长【注意开根号】
1283 最小周长 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注 一个矩形的面积为S,已知该矩形的边长都是整数,求所有 ...
随机推荐
- Ubuntu 16.04或14.04里下安装搜狗输入法(图文详解)(全网最简单)
不多说,直接上干货! 其实啊,很简单 分三步走 1.添加fcitx的键盘输入法系统,因为sogou是基于fcitx的,而系统默认的是iBus: 2.安装sogou输入法: 3.设置系统参数及一些注意点 ...
- git工具的安装和使用
啰嗦几句: 世界上本没有后悔药,但软件开发提供了后悔药,那就是代码管理工具.它可以让你的代码穿越回以前的状态,甚至可以指定某一个时刻,而且还可以穿越回来. 当下流行的代码管理工具有 SVN 和 GIT ...
- [转]C#多线程和线程池
鸣谢原文:http://www.cnblogs.com/wwj1992/p/5976096.html 1.概念 1.0 线程的和进程的关系以及优缺点 windows系统是一个多线程的操作系统.一个程 ...
- week7_notebooke
回顾:类:具有相同属相和技能的一类事物对象:类的具体表现class A: country = 'China' #静态变量,静态字段 def __init__(self): #动态变量,方法 self. ...
- 获取浏览器端的cookie方法
代码如下: function getCookie(key){ var cookies=document.cookie; if(cookies.length>0){ var start=cooki ...
- html格式的文档转成word下载
当我们前端使用ueditor插件来让用户输入数据,保存至数据库.在另一个地方需要打印用户输入的内容的时候可以用到.因为要将ueditor带格式保存下来保存的就是html格式的内容,后台转化如下: @R ...
- vue封装http请求
import axios from 'axios' import isObject from 'lodash/isObject' const http = function (api, data = ...
- Vue学习之路第三篇:插值表达式和v-text的区别
上一篇说到插值表达式有一个问题: 页面频繁刷新或者网速加载很慢的时候,页面会先出现“{{ msg }}”,再一闪而过出现真实的数据. 对于这个问题Vue给予了解决办法,看具体事例. <div i ...
- HDU 1222 Wolf and Rabbit( 简单拓欧 )
链接:传送门 题意:狼抓兔子,狼从 0 出发沿逆时针寻找兔子,每走一步的距离为 m ,所有洞窟的编号为 0 - n-1 ,问是否存在一个洞窟使得兔子能够安全躲过无数次狼的搜捕. 思路:简单的拓展欧几里 ...
- POJ 3370 Halloween treats( 鸽巢原理简单题 )
链接:传送门 题意:万圣节到了,有 c 个小朋友向 n 个住户要糖果,根据以往的经验,第i个住户会给他们a[ i ]颗糖果,但是为了和谐起见,小朋友们决定要来的糖果要能平分,所以他们只会选择一部分住户 ...