嗯,看到最近yyl大神刷了很多题(lzw大神也是),于是我翻开他们的记录,轻轻点开他们刷过的题(这句话似曾相识?)妈旦这么水的题我竟然没过!!!,然后有了这篇文.
第一题,最大连续子序列之和
良心锑星题,然后我很开心的把它艹过去了嗯.
#include <cstdio> int f,i,j,n,m,p; int main(){ m=1<<31; scanf("%d",&n); for(i=0;i<n;++i){ scanf("%d",&j); if(f<0){ p=0; f=0; } ++p; f+=j; if(p&&f>m) m=f; } printf("%d",m); return 0; }
就是这样啦.
第二题,来自USACO 2014 Jan Silver,Recording the Sczolympics
萌萌哒题啊. USACO的题都超moe的,特别是Farmer John和Bessey搞姬嗯.
(内存好小嗷我要上8 路 E7 8870 加 16TB 内存的台式嘛! 最好搞三十二张农企W9100就更棒了! 秒Top 500 rank 500 好吗?耗电有点疯狂啊, 散热还得上液氦,超频超到5.5GHz吧. 不想用980, 就这么定啦. (别YY了好吗))
翻译(官方题解,地址)
When you can only record one program at a time this problem is relatively straightforward.当你每次只能记录一个节目时题目是相当直白啊.The next program you should record is always the program that ends soonest and has not yet started.将记录下一个节目时显然有记录最接近此时起始的策略.Unfortunately, if you use this approach to schedule the first tape and then again (after removing those programs already recorded) to schedule the second tape you may not be able to schedule everything you want.但是如果你用这个方法来作为时间表先记录第一卷磁带(声道吧)再同样处理第二卷你可能就不能得到你想要的答案了.The simplest test case that demonstrates this is illustrated below.最简单的例子如下: Track 1 : |-| |-| |---------| Track 2 : |---------| |-| |-| If you put all of the small programs on the same track it becomes impossible to schedule the larger program. So an alternate approach is needed. 如果你将所有短小的节目都放在一个声道记录就不可能转播时间更长的节目了. One approach is to use dynamic programming. Our state can be described as the last two programs that were recorded on each track.有一个策略即是用动态规划.状态是我们能记录的最后俩状态节目.We can attempt to put any program that starts later than those two programs on either track if it starts after the current program on that track ends. 我们可以尝试将每个满足这个节目的起始时间在其中一个音轨的最后一个节目的结束时间之后的节目置入这个音轨. It is important, however, that we restrict to only programs that start after the last recorded programs on each track.很重要的一件事就是我们必须使的这个节目的起始时间相较俩已经在轨道中的节目为后.Otherwise we may attempt to record the same program on both tracks which would incorrectly inflate the answer. 不然我们也许会在同时记录俩同样的节目(呵呵). Alternatively, there is a more efficient greedy algorithm that does correctly solve this problem.不过这个问题有个更方便快捷的贪心解法.The algorithm works by considering programs in order of ascending end times, tracking what the last two programs recorded on each track were.我们需要把每个节目按结束时间升序排列,追踪在两个阴道音道上最后记录的节目.If the program starts before either track‘s program finishes then the program cannot be scheduled.如果这个节目结束于这两个声道已有的最早的节目结束之前,这个节目就不能被记录.If it fits on only one track it should be scheduled there. Otherwise the program should be greedily scheduled on the track with the later ending current program. 如果只有一个声道满足要求那就记录到这个声道.不然记录到结束晚的那个. This approach is based on the idea that, considering the programs in this order, we should always assign a program to a track if we can.这个想法基于我们通过这个顺序考虑节目时,我们总是能(机智滴)把可以记录的节目记录进去.This is because all later tracks we will consider have a later start time and therefore further constrain the track.这是因为所有被后考虑的节目都会使下一个节目可以开始记录的时间拖延.(真TM机智啊)In the case that the program can fit on either track we should assign to the track which already has the later ending program.这样的话如果一个节目可以记录到两个音道中就把它记录到更晚结束的那个音道中.(收音机一拍大腿)This may allow us to assign tracks that start earlier (and end later) in the future.那样可以让我们考虑起始更早的节目啦.
真机智...然后开始拍代码.
然后机智地8分钟拍完了.然后出题老师不厚道!一定要把数据范围提到500000才爽嘛!(然后$\text{O}\left( n \log{n} \right)$ 的算法居然 跑!了!一!毫!秒! 泪目...)
睡觉了,好晚了啊~~
(发Algorithm不留Code,菊花万人捅~~~)
//于是机智的我把代码补上了哈哈哈哈哈我真机智啥时请你上青龙山吃无花果? #include <cstdio> #include <algorithm> struct nd{ int s,e; } f[300]; int n,i,j,a,b,t; bool cmp(nd a,nd b){ return a.e<b.e; } int main(){ scanf("%d",&n); for(i=0;i<n;++i){ scanf("%d%d",&a,&b); f[i].s=a; f[i].e=b; } std::sort(f,f+n,cmp); a=b=0; for(i=0;i<n;++i){ t=f[i].s; if(t<a) continue;//if f is earlier than we might record, skip it if(t<b){ a=b; b=f[i].e; ++j; }else{ b=f[i].e; ++j; } } printf("%d",j); return 0; }
时间: 2024-10-10 18:02:20