题目链接:

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. js跳转方式 【转】

    第一种:    <script language="javascript" type="text/javascript">           wi ...

  2. js 常见的小数取整问题

    1.四舍五入取整 Math.round(5/2)   // 3 2.直接去掉小数,取整 parseInt(5/2);     //  2 3.向上取整,有小数整数部分就加1 Math.ceil(1/3 ...

  3. Gibonacci number-斐波那契数列

    Description In mathematical terms, the normal sequence F(n) of Fibonacci numbers is defined by the r ...

  4. web面试常见问题补充

    jquery Ajax $ajax({ Url:”test.html”,-----发送请求的地址 Async:true;------异步操作 Cache:true,-----可以从缓冲中加载 Type ...

  5. HDU-2553

    N皇后问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  6. 前端开发利器 Sublime Text 3 使用技巧和总结笔记

    这篇文章是本人在使用该工具进行前端开发的自我总结,思路也许不是很清楚,不过还是希望对读者的你有所帮助,千万别把这边文章收藏起来发霉哦,无论背多少次快捷键,还不及自己多实际操作几次. 目前官方版正式版 ...

  7. 在linux上部署tomcat服务

    在linux上部署tomcat 1.安装JDK 2.下载tomcat http://tomcat.apache.org/download-70.cgi 3.上传到服务器,并解压 4.上传war包或者已 ...

  8. (水题)洛谷 - P2439 - 阶梯教室设备利用 - 简单dp

    https://www.luogu.org/fe/problem/P2439 很明显时间是一个维度,按照时间顺序决策就行了. dp[i]表示以时间i为结尾所能达到的最长演讲时间. #include & ...

  9. Educational Codeforces Round 19 A, B, C, E(xjb)

    题目链接:http://codeforces.com/contest/797 A题 题意:给出两个数n, k,问能不能将n分解成k个因子相乘的形式,不能输出-1,能则输出其因子: 思路:将n质因分解, ...

  10. 洛谷P3857 [TJOI2008]彩灯(线性基)

    传送门 线性基裸题 直接把所有的状态都带进去建一个线性基 然后答案就是$2^{cnt}$($cnt$代表线性基里数的个数) //minamoto #include<cstdio> #inc ...