Music in Car CodeForces - 746F

题意很难懂啊...

题意:http://blog.csdn.net/a838502647/article/details/74831793

题意是说找出一个连续区间,使得区间内所有a值之和最大。对区间的要求:区间内可以选出最多k个b值(题目用的是t,但是我换成了b)减去一半(如果b是奇数就减去(b-1)/2,偶数就减去b/2),要求减完后所有b值之和不超过w。

方法:

连续区间,所以尺取(two pointers?),就是实现方法感觉好...好糟糕...

显然,对于某个确定的区间,要选出其中b最大的k个数(如果整个区间都没有k个就是全部)减半。这样对于这个区间最好。

那么,如果现在检查到了满足条件的区间[l,r],然后进一步检查到了[l+1,r],那么当前区间显然仍然是合法的(消耗时间一定减少了);r显然可以直接继续向右扩展,而不用从l+1开始遍历检查。

那么,用一个数组c记录每个b能减去的值(其实可以不用,这里只是为了方便);维护两个数组,一个q1记录当前区间中c最大的k个值,另一个q2记录当前区间剩下的c;另开一些变量记录当前区间b总和与能减去的c总和,还有愉悦值总和。只需要在区间两端进行插入或删除操作,这样每次操作都只需要进行少量的更新以维护数组、变量。

由于需要动态求数组的最大、最小值,可以用set。和需要手动维护。

set操作方法:

(插入/删除的数据为X(pair<int(c值),int(编号)>))

当在区间右侧加入时:
如果q1的size小于k,那么直接插入q1;
否则,如果q1最小的小于X,那么将q1最小的取出放入q2,将X放入q1。

当在区间左侧删除时:
如果q1的size为0,那么不删除;
否则:
如果q1最小的大于X,那么在q2中删除,否则在q1中删除;
**曾经忘记:如果在q1中删除的且q2的size大于0那么从q2中取出最大的放入q1。

别人的代码(好看多了):http://www.cnblogs.com/y119777/p/6204515.html

 #include<cstdio>
#include<set>
using namespace std;
typedef pair<int,int> P;
set<P> q1,q2;//q1当前区间的被减半的,q2当前区间剩余的
int l=,r=,n,w,k,sum1,sum2,sum3,ans;
//当前区间:sum2当前区间时间总和,sum1被减半的量,sum3总愉悦值
int a[],b[],c[];//c就是减去的量
int main()
{
bool fl;
int i;
scanf("%d%d%d",&n,&w,&k);
for(i=;i<=n;i++)
scanf("%d",&a[i]);
for(i=;i<=n;i++)
scanf("%d",&b[i]),c[i]=b[i]/;
P X,Y;
while(l<=n)
{
fl=false;
while(fl==false&&r<n)
{
X=P(c[r+],r+);
if(q1.size()<w)
{
if(sum2-sum1+b[r+]-c[r+]<=k)//如果插入后时间不超过k
{
r++;
q1.insert(X);
sum2+=b[r];
sum1+=c[r];
sum3+=a[r];
}
else
fl=true;//如果插入后时间超过k了,就不能插入了
}
else
{
Y=*q1.begin();
if(Y<X)
{
if(sum2+b[r+]-(sum1-Y.first+X.first)<=k)//如果插入后时间不超过k
{
r++;
q2.insert(*q1.begin());
q1.erase(q1.begin());
q1.insert(X);
sum2+=b[r];
sum1=sum1-Y.first+X.first;
sum3+=a[r];
}
else
fl=true;
}
else
{
if(sum2+b[r+]-sum1<=k)//如果插入后时间不超过k
{
r++;
q2.insert(X);
sum2+=b[r];
sum3+=a[r];
}
else
fl=true;
}
}
}
ans=max(ans,sum3);
if(q1.size()>)
{
X=P(c[l],l);
Y=*q1.begin();
if(Y>X)
{
q2.erase(X);
sum2-=b[l];
sum3-=a[l];
}
else
{
q1.erase(X);
sum2-=b[l];
sum3-=a[l];
sum1-=c[l];
if(q2.size()>)
{
Y=*q2.rbegin();
q1.insert(Y);
sum1+=Y.first;
q2.erase(Y);
}
}
}
l++;
}
printf("%d",ans);
return ;
}

Music in Car CodeForces - 746F的更多相关文章

  1. Codeforces 746F Music in Car

    Music in Car 用两个Set维护一下尺取的过程. #include<bits/stdc++.h> #define LL long long #define fi first #d ...

  2. Music in Car CodeForces - 746F (贪心,模拟)

    大意: n首歌, 第$i$首歌时间$t_i$, 播放完获得贡献$a_i$, 最多播放k分钟, 可以任选一首歌开始按顺序播放, 最多选w首歌半曲播放(花费时间上取整), 求贡献最大值. 挺简单的一个题, ...

  3. Codeforces Round #386 (Div. 2) 746F(set的运用)

    题目大意 给出一个歌单(有n首歌),每个歌都有愉悦值和时间,你可以选择从第x首歌开始听(也就是选择连续的一段),并且你可以选择w首歌让它的时间减半,限制时间为k,求最大的愉悦值 首先我们需要贪心一下, ...

  4. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  5. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  6. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  7. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  8. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  9. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

随机推荐

  1. vc++6.0中右键点击"转到定义"为什么是"未定义符号"呢?

    VC的问题,需要生成一下浏览信息...然后rebuild

  2. Vue 之 npm 及 安装的包

    1  npm相关 1.1 npm 是 基于Node.js 的,所以要先安装Node.js 在浏览器地址栏输入https://nodejs.org/en/, 进入Node.js官网后,点击下载左边的稳定 ...

  3. java的gradle项目的基本配置

    plugins { id 'org.springframework.boot' version '2.1.4.RELEASE' id 'java' } apply plugin: 'io.spring ...

  4. Session 钝化机制

  5. mongodb的安装、配置、常见问题

    一.MongoDB下载 mongodb可以在官网找到下载链接,找到合适的版本进行下载.下载地址->https://www.mongodb.com/download-center?jmp=nav# ...

  6. HDU3533 Escape —— BFS / A*算法 + 预处理

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533 Escape Time Limit: 20000/10000 MS (Java/Others)  ...

  7. linux初级学习笔记一:linux操作系统及常用命令,及如何获取命令的使用帮助!(视频序号:02_1,2)

    本节学习的命令:ls,cd,type,pwd, printenv, hash, date, clock, man, hwclock, info, cal, echo, printf, file! 本节 ...

  8. Maze 解题报告

    Maze Description   You are given a special Maze described as an n*m matrix, please find the shortest ...

  9. RecyclerView 局部刷新(获取viewHolder 去刷新)

    RecyclerView.ViewHolder viewHolder = mRecyclerView.findViewHolderForAdapterPosition(i); if (viewHold ...

  10. MySQL 优化之 EXPLAIN 关键字

    MySQL查询优化之explain的深入解析 0. 准备 首先执行如下的 sql 语句: CREATE TABLE IF NOT EXISTS `article` (`id` int(10) unsi ...