Music in Car CF 746F

题目:http://codeforces.com/problemset/problem/746/F

先感叹一下题目之长!

一些测试样例在后面给出。

题目大意:

Sasha 去工作的路上喜欢听歌,途中经历 K 分钟,有一个歌单,顺序播放。

每首歌都对应一个开心值 ai ,持续时间为 ti 分钟

开始的时候先选定一首歌曲,例如第x首,从这首歌开始顺序播放,终止条件为:歌单播放完或行程到终点了

一首歌可以播放整首或只播放一部分,后者必须播放歌曲的一半时间(取上整)以上才能获得对应的开心值。

播放一部分还有一个曲目数量限制为w,只有w首歌曲支持半曲播放。

问:确定n w  k 的情况下,Sasha能够获取的最大开心值。

思路:

设定两个set 容器,一个存整首曲目,一个存半曲曲目。想要在固定的时间K 之内听更多的歌曲开心值更高,而且必须是连续的曲目,那就要把时间长的尽量折半,把时间短的让出来按整首去听。所以,刚开始都先把歌曲按半曲存,如果半曲列表满了之后,再根据情况选择性弹出,替换。当K 时间用完之后,就从左边开始删歌曲,保证后面遍历完所有的情况,因为,可以从中任何一首歌曲开始听。这样求取过程中产生的最大开心值即可。半曲列表最大容量为w,原来用的加法做,感觉有点复杂,后来改了减法,这个看个人喜好。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<set>
 4 using namespace std;
 5 int arr[200005];
 6 int happy[200005];
 7
 8 inline long max(long x, long y)
 9 {
10     return x > y ? x : y;
11 }
12
13 int main()
14 {
15     long N, W, K;
16     while (scanf("%ld %ld %ld", &N, &W, &K) != EOF)
17     {
18         long result = 0, RESULT = 0;
19         set<pair<int, int> >S_, S;          //分别代表半曲容器和整首容器
20         for (int i = 1; i <= N; ++i)
21             scanf("%d", happy + i);
22         for (int i = 1; i <= N; ++i)
23             scanf("%d", arr + i);
24         int l, r;
25         l = r = 1;
26         while (r <= N)
27         {
28             //right pointer;
29             while (r <= N)
30             {
31                 if (W)
32                 {
33                     if (K >= (arr[r] + 1) / 2)
34                     {
35                         K -= (arr[r] + 1) / 2;
36                         RESULT = max(RESULT, result += happy[r]);
37                         S_.insert(make_pair(arr[r], r));
38                         r++;
39                         W--;
40                     }
41                     else break;             //行程结束
42                 }
43                 else      //如果w位置已满
44                 {
45                     int tmp = S_.begin()->first;
46                     if (tmp <= arr[r] && K >= (arr[r] + 1) / 2 - (tmp + 1) / 2 + tmp)  //如果当前的比半曲列表中时间最短的花费时间长,替换
47                     {
48                         K -= (arr[r] + 1) / 2 - (tmp + 1) / 2 + tmp;
49                         RESULT = max(RESULT, result += happy[r]);
50                         auto p = S_.begin();
51                         S.insert(*p);
52                         S_.erase(p);
53                         S_.insert(make_pair(arr[r], r));
54                         r++;
55                     }
56                     else if (tmp > arr[r] && K >= arr[r])         //如果当前的比半曲列表中时间最短的还短,那么就把当前的短歌放入S
57                     {
58                         K -= arr[r];
59                         RESULT = max(RESULT, result += happy[r]);
60                         S.insert(make_pair(arr[r], r));
61                         r++;
62                     }
63                     else break;
64                 }
65             }
66             //left pointer;   K时间已经满了,从左边开始删除歌曲,以保证继续往后遍历
67             if (l < r)
68             {
69                 if (S.find(make_pair(arr[l], l)) != S.end())
70                 {
71                     K += arr[l];
72                     result -= happy[l];
73                     S.erase(make_pair(arr[l], l));
74                 }
75                 else
76                 {
77                     K += (arr[l] + 1) / 2;
78                     result -= happy[l];
79                     S_.erase(make_pair(arr[l], l));
80                     W++;
81                     if (!S.empty())
82                     {
83                         auto p = --S.end();
84                         K += p->first - (p->first + 1) / 2;
85                         S_.insert(*p);
86                         W--;
87                         S.erase(p);
88                     }
89                 }
90                 l++;
91             }
92             else l++, r++;
93         }
94         printf("%d\n", RESULT);
95     }
96 }

Sample Input

6 4 10
2 4 5 20 4 8
6 3 5 20 8 7

6 4 10
7 7 8 20 3 7
6 3 5 20 8 7

5 3 12
20 2 1 2 3
16 6 2 4 3

Sample Output

20
22
23

感谢您的阅读,生活愉快~

原文地址:https://www.cnblogs.com/lv-anchoret/p/8461705.html

时间: 2024-08-30 07:22:47

Music in Car CF 746F的相关文章

微信 {&quot;errcode&quot;:40029,&quot;errmsg&quot;:&quot;invalid code, hints: [ req_id: Cf.y.a0389s108 ]&quot;}

{"errcode":40029,"errmsg":"invalid code, hints: [ req_id: Cf.y.a0389s108 ]"} 问题:微信网页授权后,获取到 openid 了,一刷新又没了 微信网页授权获取到的 code 只能使用一次(5分钟内有效),使用一次后,马上失效. 页面授权跳转成功,根据 code 也换取到 openid 了. 此时刷新页面,并不会再次进行授权,而是直接刷新了一下上一次授权跳转后的链接,带的还是

CF with friends and user&#39;s influence considered on NYC data(updated Aug,11st)

Here is the code link: https://github.com/FassyGit/LightFM_liu/blob/master/U_F1.py I use NYC data as other experimens. The split of the training data was seperated by the timeline, and I have normalised the interaction matrix by replacing the checkin

CF 750

今天CF打的块残废了     就是一废物 A 在24点之前到 直接模拟即可 #include<stdio.h> #include<algorithm> #include<cstring> #include<string> #include<cmath> using namespace std; #define LL long long #define MAXN 1010 #define inf 1000000000.0 int main() {

CF #394 (2) 5/6

Codeforces Round #394 (Div. 2) 总结:有毒的一场比赛.做了三题,结果A被叉,B.C挂综测,还hack失败一发,第一次在CF体会到了-50分的感觉..不知道是不是人品好,比赛时room炸了,然后,unrated.. A  水题,判一下0 0,然后abs(a-b)<=1 B  水题,组个间距比较一下,但一个数的时候要判一下 C  直接暴力上的题 D  也是xjb暴力 题意:给出n,l,r, a[], p[],另有两个数组b[], c[],ci=bi-ai.l<=ai,

一场CF的台前幕后(上)——转

前奏 大约4月份的时候,业界毒瘤pyx噔噔噔跑过来说:“酷爱!我YY了一道题!准备当CF的C” 我当时就被吓傻了."Yet another Chinese round?" “区间取模,区间求和” 感觉这题还不错?不过pyx嫌水了…… 好办!当时我刚刚出完动态仙人掌不久,于是一拍脑袋说:把这个问题出到仙人掌上去! 当然被pyx鄙视了…… 后来一直就没啥动静,直到5月底的CTSC. 试机的时候pyx给我看了套他出的神题……里面有一道题……我不小心读成了下面这个样子: “给定n个m维的模2意

[2016-03-22][CF][69A][Young Physicist]

时间:2016-03-22 19:41:34 星期二 题目编号:[2016-03-22][CF][69A][Young Physicist] 题目大意:判断向量和是否为0 分析:对应坐标相加 遇到的问题:不能用x+y+z来判断是否都为0,除非输入都是正数 #include <cstdio> using namespace std; int main(){ int a,b,c,x,y,z,n; x = y = z = 0; scanf("%d",&n); for(in

ARC下OC对象和CF对象之间的桥接(bridge)

在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环境下编译器不会自动管理CF对象的内存,所以当我们创建了一个CF对象以后就需要我们使用CFRelease将其手动释放,那么CF和OC相互转化的时候该如何管理内存呢?答案就是我们在需要时可以使用__bridge,__bridge_transfer,__bridge_retained,具体介绍和用法如下

【CF 520D】Cubes

[CF 520D]Cubes 怎么说呢--英语阅读题+超级大模拟-- 最重要的是知道怎么出来的数据...题意好懂 xy坐标内给出几个单位正方形 以正方形左下点坐标给出 y=0为地面 正方形下面或者左右下方至少存在一个正方形他才能稳定.. 正方形按0~m-1标号 每次只能取出不影响整体结构的正方形 甲乙玩一个游戏 交替取正方形 每取下一个按从左到右的顺序排好 得到一个大数 重点来了! 取出的数是m进制 转换为十进制是最终结果 甲希望结果最大 乙希望结果最小 问结果为多少 甲先取 题意明白了模拟就行

cf 148D Bag of mice

The dragon 选一只老鼠,然后会跑掉一只 the princess选一只老鼠,不会跑出另外的老鼠 求the princess赢的概率 1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 #include<vector> 5 #include<queue> 6 #include<stack> 7 #include<algorithm> 8 #inc