题目链接:

http://codeforces.com/problemset/problem/747/D

题目大意:

接下来的n天内每天都有一个气温,如果某天的温度为负数,则必须使用冬季轮胎;而温度非负,则既可以使用冬季轮胎,也可以使用夏季轮胎。开始的时候车子上装的是夏季轮胎,如果连续两天使用的轮胎类型不同,则需要换胎。规定使用冬季轮胎的总天数不能超过k,问换胎的最少次数。(注:n天结束后车子上装的既可以是冬季轮胎,也可以是夏季轮胎)。

解题思路:

一开始想到dp+滚动数组。然而时间复杂度太高,查了tutorial发现可以贪心。具体来说就是:

1.当温度为负数的天数之和大于k时,无解。

2.否则令k减去温度为负数的天数之和。并求出所有连续的温度为负数的区段的个数cnt,此时换胎次数x最多为cnt*2。

3.求出所有连续的温度为非负数的区段,并将这样的区段的长度push到一个小顶堆中。先不考虑持续到第n天的非负区段(如果有的话),不要将这样的区段放入堆中(之后判断这种特殊情况)。也不必考虑从第1天开始持续到第一个负区段之前的非负区段,因为一开始车子上的是夏季轮胎,这样的区段不会影响最终结果。

4.当堆不空并且k大于等于堆顶元素的时候,将堆顶元素pop出来,同时将k减去堆顶元素,并且令x -= 2。(相当于贪心地合并掉非负区段)

5.考虑特殊情况:如果存在一个非负区段并且这个区段持续到第n天,并且此时k大于等于这个区段的长度,则可以x--(相当于最后一次不换回夏季轮胎,省掉一次换胎操作);或者最后一个负区段持续到第n天,这种情况也可以省掉一次换回夏季轮胎的操作,也要x--。总之,无论持续到n天的最后一个区段是负区段还是非负区段,都要x--。这样就得到了最终答案。

其实思路不是很难想,但是实现起来需要注意一些细节。

代码写得不是很漂亮:

 #include <iostream>
#include <cstdio>
#include <queue>
#include <functional>
#include <vector>
using namespace std; int a[], n, k;
int find_non_negtive_start(int pos)
{
for (int i = pos; i < n; i++)
{
if (a[i] >= )
return i;
}
return -;
}
int find_non_negtive_end(int pos)
{
for (int i = pos; i < n; i++)
{
if (a[i] < )
return i - ;
}
return -;
}
int find_negtive_start(int pos)
{
for (int i = pos; i < n; i++)
{
if (a[i] < )
return i;
}
return -;
}
int find_negtive_end(int pos)
{
for (int i = pos; i < n; i++)
{
if (a[i] >= )
return i - ;
}
return -;
}
int main()
{
priority_queue<int, vector<int>, greater<int> > q;
cin >> n >> k;
int cnt = , cnt_negtive = ;
int start = -, begin = -;
for (int i = ; i < n; i++)
{
scanf("%d", &a[i]);
if (a[i] < )
{
cnt++;
if (begin == -)
begin = i;
}
else
{
if (begin != - && start == -)
start = i;
}
}
if (cnt > k)
{
cout << "-1" << endl;
return ;
}
if (cnt == )
{
cout << "" << endl;
return ;
}
if (start == -)
{
cout << "" << endl;
return ;
}
if (begin == -)
{
cout << "" << endl;
return ;
}
cnt_negtive = cnt;
cnt = ;
while ()
{
int pos = find_negtive_end(begin + );
if (pos == -)
{
cnt++;
break;
}
cnt++;
begin = find_negtive_start(pos + );
if (begin == -)
break;
}
cnt *= ;
int res = -;
while ()
{
int pos = find_non_negtive_end(start + );
if (pos == -)
{
res = n - start;
break;
}
q.push(pos - start + );
start = find_non_negtive_start(pos + );
if (start == -)
{
break;
}
}
k -= cnt_negtive;
while (!q.empty())
{
if (k >= q.top())
{
k -= q.top();
q.pop();
cnt -= ;
}
else
{
break;
}
}
if (k >= res)
{
cnt--;
}
cout << cnt << endl;
return ;
}

CF747D Winter Is Coming的更多相关文章

  1. 开发框架Data Abstract和Hydra发布版本Winter 2013

    Data Abstract Winter 2013即Data Abstract Version 7.0.73 (Build .1111),Winter 2013版对Data Abstract继续做了以 ...

  2. 2015 UESTC Winter Training #10【Northeastern Europe 2009】

    2015 UESTC Winter Training #10 Northeastern Europe 2009 最近集训都不在状态啊,嘛,上午一直在练车,比赛时也是刚吃过午饭,状态不好也难免,下次比赛 ...

  3. 2015 UESTC Winter Training #8【The 2011 Rocky Mountain Regional Contest】

    2015 UESTC Winter Training #8 The 2011 Rocky Mountain Regional Contest Regionals 2011 >> North ...

  4. 2015 UESTC Winter Training #7【2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest】

    2015 UESTC Winter Training #7 2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest 据 ...

  5. 2015 UESTC Winter Training #6【Regionals 2010 >> North America - Rocky Mountain】

    2015 UESTC Winter Training #6 Regionals 2010 >> North America - Rocky Mountain A - Parenthesis ...

  6. 2015 UESTC Winter Training #4【Regionals 2008 :: Asia - Tehran】

    2015 UESTC Winter Training #4 Regionals 2008 :: Asia - Tehran 比赛开始时电脑死活也连不上WIFI,导致花了近1个小时才解决_(:зゝ∠)_ ...

  7. Winter(bfs&&dfs)

    1084 - Winter   PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Winter is ...

  8. Codeforces 839D Winter is here【数学:容斥原理】

    D. Winter is here time limit per test:3 seconds memory limit per test:256 megabytes input:standard i ...

  9. Codeforces Round #428 (Div. 2) D. Winter is here 容斥

    D. Winter is here 题目连接: http://codeforces.com/contest/839/problem/D Description Winter is here at th ...

随机推荐

  1. Swift扩展

    Swift中的「扩展」(extensions)和OC中的categories类似,只是Swift中的「扩展」没有名字.Swift中的「扩展」可以向一个已有的类/结构体/枚举类型添加新功能,这包括在没有 ...

  2. LOJ114 k大异或和

    传送门 (vjudge和hdu也有但是我觉得LOJ好看!而且限制少!) 不过本题描述有误,应该是k小. 首先我们需要对线性基进行改造.需要把每一位改造成为,包含最高位的能异或出来的最小的数. 为啥呢? ...

  3. codevs 2102 石子归并2

    传送门 2102 石子归并 2  时间限制: 10 s  空间限制: 256000 KB  题目等级 : 黄金 Gold   题目描述 Description 在一个园形操场的四周摆放N堆石子,现要将 ...

  4. Numpy 小结

    Python 真火来学习一下,先来看一个库 NumPy.NumPy是Python语言的一个扩充程序库.支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库. 1. 读取文件 num ...

  5. 解决最近windows版本Node.js中npm出现的“Error: ENOENT, stat 'C:\Users\UserName\AppData\Roaming\npm”的问题

    (转载请注明出处,from www.cnblogs.com/xdxer) 问题可能如下所示 解决方案: 在 'C:\Users\UserName\AppData\Roaming\‘ 下手动的增加一个文 ...

  6. Ubuntu12.04下安装、使用、卸载MySQL

    转自:http://blog.csdn.net/yimi0903/article/details/11800713 一.安装 Step1:安装MySQL-server,mysql-client 执行以 ...

  7. CF-831C

    C. Jury Marks time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

  8. 【Linux学习】Linux文件系统1--文件系统的目录结构

    Linux文件系统1--文件系统的目录结构 一.linux文件系统的类型 LINUX有四种基本文件系统类型:普通文件.目录文件.连接文件和特殊文件,可用file命令来识别. 1.普通文件:如文本文件. ...

  9. Makefile研究(三) —— 实际应用

    转自:http://blog.csdn.net/jundic/article/details/17886637 前面讲了Makefile 的简单语法和简单的应用模板,但在实际项目应用中比这个肯定复杂很 ...

  10. UVa 10214 Trees in a Wood. (数论-欧拉函数)

    题意:给定一个abs(x) <= a, abs(y) <= b,除了原点之外的整点各有一棵树,可以相互阻挡,求从原点可以看到多少棵树. 析:由于a < b,所以我们可以一列一列的统计 ...