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,已知该矩形的边长都是整数,求所有 ...
随机推荐
- HD-ACM算法专攻系列(19)——Leftmost Digit
问题描述: AC源码: 解题关键是,数据很大,不能强算,需要使用技巧,这里使用科学计算法,令N^N=a*10^n ,取对数后变为 N*log10(N)=log10(a)+n,令x = log10(a) ...
- 开发辅助 | 前端开发工程师必懂的 UI 知识
移动 UI 设计的世界 ... 1.屏幕尺寸 屏幕大小,指屏幕对角线的长度,而不是屏幕的宽度或高度: 单位为英寸 如 iPhone 7 屏幕尺寸为 4.7 英寸:三星 S6 屏幕尺寸为 ...
- android 给imageView,文字等加上阴影[记录]
1.链接 https://github.com/Devlight/ShadowLayout 2.效果 3.code compile 'com.github.devlight.shadowlayout: ...
- 双向链表C++实现
双向链表实现,通过C++实现 #ifndef LinkList_hpp #define LinkList_hpp typedef struct Node{ int data; Node* next; ...
- 学习supervisor
学习supervisor doc: http://supervisord.org http://lixcto.blog.51cto.com/4834175/1539136 命令 安装:pip inst ...
- [读书笔记] R语言实战 (四) 基本数据管理
1. 创建新的变量 mydata<-data.frame(x1=c(2,2,6,4),x2=c(3,4,2,8)) #方法一 mydata$sumx<-mydata$x1+mydata$x ...
- Ansible学习记录四:单命令测试
0.Ansible的group支持all.通配符(*).IP地址 1.查看Ansible的版本 $ ansbile --version [root@test ~]# ansible --versi ...
- MBR和GPT分区学习
1.MBR 早期的windows和linux都采用的MBR的方法来处理开机引导程序和分区表,对于linux的MBR分区来讲,0柱面0磁道1扇区用于引导驱动程序,第一扇区有512个字节,前446字节存放 ...
- multiple definition of
总结了解决multiple definition of的方法: 问题原因: 当多个文件包含同一个头文件时,并且你的.H里面没有加上条件编译#ifndef TEST_H#define TEST_H ...
- 小学生都能学会的python(函数的进阶)
小学生都能学会的python(函数的进阶) 1. 动态传参 形参: 1. 位置参数 2. 默认值参数 3. 动态传参 *args 动态接收位置参数 **kwargs 动态接收关键字参数 def fun ...