博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hihoCoder 第136周 优化延迟(二分答案+手写堆)
阅读量:5233 次
发布时间:2019-06-14

本文共 3084 字,大约阅读时间需要 10 分钟。

题目1 : 优化延迟

时间限制:
10000ms
单点时限:
1000ms
内存限制:
256MB

描述

小Ho编写了一个处理数据包的程序。程序的输入是一个包含N个数据包的序列。每个数据包根据其重要程度不同,具有不同的"延迟惩罚值"。序列中的第i个数据包的"延迟惩罚值"是Pi。如果N个数据包按照<Pi1, Pi2, ... PiN>的顺序被处理,那么总延迟惩罚

SP=1*Pi1+2*Pi2+3*Pi3+...+N*PiN(其中i1, i2, ... iN是1, 2, 3, ... N的一个排列)。

小Ho的程序会依次处理每一个数据包,这时N个数据包的总延迟惩罚值SP为

1*P1+2*P2+3*P3+...+i*Pi+...+N*PN。  

小Hi希望可以降低总延迟惩罚值。他的做法是在小Ho的程序中增加一个大小为K的缓冲区。N个数据包在被处理前会依次进入缓冲区。当缓冲区满的时候会将当前缓冲区内"延迟惩罚值"最大的数据包移出缓冲区并进行处理。直到没有新的数据包进入缓冲区时,缓冲区内剩余的数据包会按照"延迟惩罚值"从大到小的顺序被依次移出并进行处理。

例如,当数据包的"延迟惩罚值"依次是<5, 3, 1, 2, 4>,缓冲区大小K=2时,数据包被处理的顺序是:<5, 3, 2, 4, 1>。这时SP=1*5+2*3+3*2+4*4+5*1=38。

现在给定输入的数据包序列,以及一个总延迟惩罚阈值Q。小Hi想知道如果要SP<=Q,缓冲区的大小最小是多少?

输入

Line 1: N Q

Line 2: P1 P2 ... PN

对于50%的数据: 1 <= N <= 1000

对于100%的数据: 1 <= N <= 100000, 0 <= Pi <= 1000, 1 <= Q <= 1013

输出

输出最小的正整数K值能满足SP<=Q。如果没有符合条件的K,输出-1。

样例输入
5 385 3 1 2 4
样例输出
2

题目链接:

题目非常明显就是裸的二分答案,想测试的堆看看手写的是不是有问题,以及速度如何,比封装的pq要快一些前者700ms+后者1000ms+,方便起见我的堆是递归形式的,非递归就不是很熟了。

代码:

#include 
#include
using namespace std;#define INF 0x3f3f3f3f#define LC(x) (x<<1)#define RC(x) ((x<<1)+1)#define MID(x,y) ((x+y)>>1)#define CLR(arr,val) memset(arr,val,sizeof(arr))#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);typedef pair
pii;typedef long long LL;const double PI = acos(-1.0);const int N = 100010;LL arr[N];int n;LL q;struct heap{ LL a[N]; int sz; void init() { sz = 0; } void up(const int &cur) { int fa = cur >> 1; if (fa > 0 && a[cur] > a[fa]) { swap(a[cur], a[fa]); up(fa); } } void down(const int &cur) { int lson = cur << 1, rson = cur << 1 | 1; if (lson > sz) return ; else { int tar; if (rson > sz) tar = lson; else tar = a[lson] > a[rson] ? lson : rson; if (a[cur] < a[tar]) { swap(a[tar], a[cur]); down(tar); } } } void push(int x) { a[++sz] = x; up(sz); } void pop() { swap(a[sz--], a[1]); down(1); } LL top() { return a[1]; } bool empty() { return !sz; }};heap one;bool check(const int &k){ one.init(); LL bas = 1LL; LL sp = 0LL; for (int i = 1; i <= k; ++i) one.push(arr[i]); for (int i = k + 1; i <= n; ++i) { sp += (bas++) * one.top(); one.pop(); one.push(arr[i]); } while (!one.empty()) { sp += (bas++) * one.top(); one.pop(); } return sp <= q;}int main(void){ int i; while (~scanf("%d%lld", &n, &q)) { for (i = 1; i <= n; ++i) scanf("%lld", arr + i); int ans = -1; int L = 1, R = n; while (L <= R) { int mid = (L + R) >> 1; if (check(mid)) { R = mid - 1; ans = mid; } else L = mid + 1; } printf("%d\n", ans); } return 0;}

转载于:https://www.cnblogs.com/Blackops/p/6370087.html

你可能感兴趣的文章
插值法(内插法)
查看>>
php 关于文件夹的一些封装好的函数
查看>>
Java并发--Java中的CAS操作和实现原理
查看>>
java1.8新特性整理(全)
查看>>
elementUI之通过指定 Table 组件的 row-class-name 属性来为 Table 中的某一行添加 class改变该行的颜色等样式。...
查看>>
小技巧
查看>>
深度学习图像配准 Image Registration: From SIFT to Deep Learning
查看>>
可分离卷积详解及计算量 Basic Introduction to Separable Convolutions
查看>>
CNN中各类卷积总结:残差、shuffle、空洞卷积、变形卷积核、可分离卷积等
查看>>
Mean Average Precision(mAP),Precision,Recall,Accuracy,F1_score,PR曲线、ROC曲线,AUC值,决定系数R^2 的含义与计算...
查看>>
win7 能ping通dns, 但无法解析域名
查看>>
centos 软件安装包下载网站
查看>>
nmap 端口扫描工具
查看>>
Excel vlookup筛选两列的重复项
查看>>
配置了BFD MAD, 在IRF正常情况下的 BFD状态是不是 down?
查看>>
SQL server 2012定期的备份数据库--完整+差异+事物
查看>>
C语言 - 可变参数再stm32中的应用
查看>>
vscode + platformIO开发stm32f4
查看>>
最新SSM框架整合2019
查看>>
LinkedList的线程安全解决办法
查看>>