最小函数值 洛谷P2085
题目描述:
有n个函数,分别为F1,F2,...,Fn。定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*)。给定这些Ai、Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个)。
输入样例:
3 10
4 5 3
3 4 5
1 7 1
输出样例:
9 12 12 19 25 29 31 44 45 54
题目分析:
(MLE,TLE做法)看到题目我们第一眼肯定想到的是将每个函数枚举m次,然后对这n*m个数进行排序,输出前m个。代码如下:
#include<cstdio>
#include<algorithm>
#define MAXSIZE 100000000+20
#define MAXN 10000+20
int a[MAXN],b[MAXN],c[MAXN];
int num[MAXSIZE]; int main(){
int n,m,k=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d%d%d",&a[i],&b[i],&c[i]);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
num[k++]=a[i]*j*j+b[i]*j+c[i];
std::sort(num+,num+k);
for(int i=;i<=m;i++)
printf("%d ",num[i]);
return ;
}
这样做的正确性是显而易见的:题目要求给出最小的M个数,这最小的M个数是由这N个函数生成的,最坏情况就是这M个数都由一个函数生成。那么即使这样,x的最大值也只是等于M,因为我们都知道:当二次函数y=ax2+bx+c(a>0)时,抛物线开口朝上,y随x增大而增大。所以当x1=i,x2=j(i,j∈N+,i<j)时y1<y2,所以我们对于同一个函数来说,x越小生成的数越小,这点在AC的算法中有很重要的作用。
通过上面所说的,我们可以得知x最大值也只是等于M,也就是说我们的枚举区间就是1~m。我们需要对每个函数都枚举一遍,所以这一步的时间复杂度是O(n*m),最高是一亿,暂时还没超时,但是这是无序的,也就是说我们要将这n*m个数排序。
假设我们用的是最快的快排,没被卡快排,那么这一步的时间复杂度就是O(n*m*log2(n*m));总体时间复杂度就是O(n*m*log2(n*m)),对于n=10000,m=10000,这个时间复杂度明显超时,况且我们还要花O(n*m)空间开销,这也是吃不消的。
(AC做法)因为全部都算出来再排序输出必然超时,所以我们必须想办法减少算出来的值。在做出TLE且MLE的做法的时候,我们就证明了对于同一个函数而言,x越小生成的数越小,那我们不难画出下面这个表:
| 与x+1的关系 | x的值 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 函数 | < | < | < | < | < | < | < | < | |
| f1 | < | < | < | < | < | < | < | < | |
| f2 | < | < | < | < | < | < | < | < | |
| f3 | < | < | < | < | < | < | < | < | |
| f4 | < | < | < | < | < | < | < | < | |
| f5 | < | < | < | < | < | < | < | < | |
| f6 | < | < | < | < | < | < | < | < | |
| f7 | < | < | < | < | < | < | < | < | |
| ... | < | < | < | < | < | < | < | < | |
假设xi=1,xj=1时fi<fj
则xi=1,xj=xj+1时fi<fj
则当只存在fi和fj时xi=1时fi为最小值
稍加思考,我们可以想到下面一种贪心算法:
一开始先取每个函数中x=1时的值,输出这中间最小的,然后将最小的更新为x=2时的情况,再输出最小的......
说到最小,就想到了用最小堆实现,代码如下:
#include<cstdio>
#include<algorithm>
#define min(a,b) (((a)<(b))?(a):(b))
using std::swap;
struct h{
int data;
int place;
}heap[+];
bool operator < (const h &X,const h &Y){ //重载小于号
return X.data<Y.data;
}
int a[+],b[+],c[+];
int x[+];
int n;
void put(int i){
while(i*+<=n){
if(min(heap[i*],heap[i*+])<heap[i]){ //比较左儿子和右儿子
if(heap[i*]<heap[i*+]){
swap(heap[i*],heap[i]);
i*=;
}else{
swap(heap[i*+],heap[i]);
i*=;
i++;
}
}else
break;
}if(i*<=n&&heap[i*]<heap[i]){
swap(heap[i*],heap[i]);
i*=;
}
} int main(){
int m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d%d%d",&a[i],&b[i],&c[i]);
for(int i=;i<=n;i++){
x[i]=; //保存每个函数的x用到了几
heap[i].data=a[i]+b[i]+c[i]; //当x=1的情况
heap[i].place=i;
}
for(int i=n;i>=;i--){
put(i); //建堆
}
for(int i=;i<=m;i++){
printf("%d ",heap[].data);
int &k=heap[].place;
heap[].data=heap[].data+*a[k]*x[k]+a[k]+b[k]; //自己去算,不想讲,初二数学--完全平方式
x[heap[].place]++;
put();
}
return ;
}
时间复杂度O((n+m)log2n),最坏情况20000*log2(10000)≈280000不会超时
空间复杂度O(n)最坏10000,约0.04MB,离上限128MB很远。
最小函数值 洛谷P2085的更多相关文章
- P2085 最小函数值 洛谷
https://www.luogu.org/problem/show?pid=2085 题目描述 有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*) ...
- 洛谷P2085 最小函数值(minval)
P2085 最小函数值(minval) 218通过 487提交 题目提供者该用户不存在 标签堆高级数据结构 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 暂时没有讨论 题目描述 有n个函数, ...
- 洛谷P2085最小函数值题解
题目 首先我们先分析一下题目范围,\(a,b,c\) 都是整数,因此我们可以得出它的函数值在\((0,+\infty )\)上是单调递增的,,然后我们可以根据函数的性质,将每个函数设置一个当前指向位置 ...
- [洛谷P2085]最小函数值
题目大意:有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*).给定这些Ai.Bi和Ci,要求出所有函数的所有函数值中最小的m个(如有重复的要输出多个 ...
- 洛谷P2085——最小函数值
题目描述 有n个函数,分别为\(F_1,F_2,...,F_n\).定义\(F_i(x)=A_i*x^2+B_i*x+C_i (x∈N*)\).给定这些\(A_i.B_i和C_i\),请求出所有函数的 ...
- 洛谷 P2085 最小函数值
目录 题目 思路 \(Code\) 题目 戳 思路 首先这些函数全部单带递增,因为\(a\),\(b\),\(c\)都是正整数. 我们将全部的函数的\(x\)为\(1\)时的函数值放入优先度列(小根堆 ...
- P1576 最小花费 洛谷
https://www.luogu.org/problem/show?pid=1576 题目背景 题目描述 在n个人中,某些人的银行账号之间可以互相转账.这些人之间转账的手续费各不相同.给定这些人之间 ...
- 洛谷P4014 分配问题【最小/大费用流】题解+AC代码
洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...
- 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码
洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...
随机推荐
- p1221网络布线(最小生成树 Prim(普里母)算法) p1222 Watering Hole
描述 Description 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助.约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路 ...
- Nginx+tomcat动静分离安装脚本
#!/bin/bashsetenforce 0systemctl stop firewalldtar -zxvf nginx-1.8.0.tar.gz -C /usr/src/ cd /usr/src ...
- VS2012 百度云下载 开发工具
百度云下载地址:链接: http://pan.baidu.com/s/1qWDIDPi密码: 5nr0 ASP.NET MVC4.0+ WebAPI+EasyUI+KnockOutJS快速开发框架 通 ...
- 第24篇 js小知识和“坑”
前面说了说了js的相关知识,基本上除了语法外,把项目常用的知识做了一个梳理,现在说下js的其它方面的知识,这些知识不成体系,属于不理解对于一般开发没什么太多影响,但如果理解清楚,可以更好去开发. js ...
- C#异步的世界【下】
接上篇:<C#异步的世界[上]> 上篇主要分析了async\await之前的一些异步模式,今天说异步的主要是指C#5的async\await异步.在此为了方便的表述,我们称async\aw ...
- HTML5之多媒体
概览 html5新增了两个关于多媒体的元素:video和audio,前者是用于视频,后者用于音频.而他们使用非常简单 <audio src="xhn.mp3" control ...
- Servlet中过滤器的执行流程
- Summary Ranges leetcode
Given a sorted integer array without duplicates, return the summary of its ranges. For example, give ...
- 1050: [HAOI2006]旅行comf
1050: [HAOI2006]旅行comf Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1495 Solved: 737[Submit][Sta ...
- JavaSE之认识java
本来很早之前就应该总结自己在JavaSE中系统学到的知识了,马上就要出去工作了,想想自己还是非常菜的菜鸟,自己就夜不能寐呀.现在从zero基础开始带大家一起回顾学习的基础知识. 现在已经是凌晨了,但是 ...