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. linux shell 突破

    targetDate=$(cat maxdayid); targartMonth=${targetDate::}; targartYear=${targetDate::}; echo $targart ...

  2. HDU 6122 今夕何夕 【数学公式】 (2017"百度之星"程序设计大赛 - 初赛(A))

    今夕何夕 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. iOS 获取WIFI SSID及MAC地址

    NSString *ssid = @"Not Found"; NSString *macIp = @"Not Found"; CFArrayRef myArra ...

  4. 自制简单的range(Vue)

    废话不多说先上成果图 实现思路 主要分界面与逻辑两大块 界面分为5个部分 左滑块长度 左内容位置 中间长度 右滑块长度 右内容位置 逻辑 touch3个事件 各滑块长度及位置计算 选中时变色 具体实现 ...

  5. POJ2516 Minimum Cost —— 最小费用最大流

    题目链接:https://vjudge.net/problem/POJ-2516 Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Tota ...

  6. 多线程、死锁、线程安全、同步方法、代码块、休眠、守护线程、Thread、Runnable(二十三)

    1.多线程的引入 * 1.什么是线程 * 线程是程序执行的一条路径, 一个进程中可以包含多条线程 * 多线程并发执行可以提高程序的效率, 可以同时完成多项工作* 2.多线程的应用场景 * 红蜘蛛同时共 ...

  7. html5--6-63 布局

    html5--6-63 布局 实例 学习要点 掌握传统布局与CSS3新增布局方式的实现和应用 掌握CSS3新增属性box-sizing 了解CSS3新增的多列布局 常用布局方式 固定布局与流体布局的优 ...

  8. MyEclipse注释配置

    MyEclipse注释配置 配置路径 1.1.      JAVA 打开MyEclipse,选择Window>Preferences>Java>Code Style>Code ...

  9. hdu2544 迪杰斯特拉题目优化

    点击打开题目链接 迪杰斯特拉的用法不多讲,详见  点击打开链接 . 下面两个代码: 这个是用邻接矩阵存图的迪杰斯特拉. #include<stdio.h> int main() { int ...

  10. 【BZOJ 2721】 樱花

    [题目链接] 点击打开链接 [算法] 令n!=z,因为1 / x + 1 / y = 1 / z,所以x,y>z,不妨令y = z + d 则1 / x + 1 / (z + d) = 1 / ...