题目链接:http://codeforces.com/problemset/problem/747/D
题意:冬天有n天,冬天用的轮胎总共能用k天,一开始车子用的是夏天的轮胎。
给出n天的平均气温,温度小于0的时候必须换上冬天用的轮胎,冬天用的轮胎
任何温度下都可以使用,问最少交换机次轮胎。
首先要找到第一个温度小于0的日子,那天肯定要换上冬天用的轮胎,然后再找
最后一个温度小于0的日子,因为在那之后就用不到冬天用的轮胎了。设最早小
于0的日子为sta,最后为end。
大情况稍微分一下
设温度小于0的天数为count
1)count = 0
输出0.
2)count > k
输出-1
3)0 < count <= k 时要分多种情况。
1.k >= n - sta + 1
输出1
2.sta - end + 1 <= k < n - sta + 1
输出2
3.k < sta - end + 1
这是要考虑如何在sta~end区间的换一下夏天用的轮胎来为冬天的轮胎续一下。
于是我们可以找sta~end之间的大于0的区间交换2次,由于我们要尽可能的少
的交换轮胎,所以我们可以找尽可能区间长的区间来换这样省了冬天轮胎使用的
天数,这里设sta~end之间减去删掉的区间总长度剩下的长度为gg,gg<=k时
就可以不用再减了,end~n的这段时间在比较一下gg+n-end与k。
1)).gg + n - end >= k
不用再加了。
2)).gg + n - end < k
再加一次
最后输出天数即可
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int M = 2e5 + 10; int a[M] , b[M]; bool cmp(int x , int y) { return x > y; } int main() { int n , k; cin >> n >> k; int count = 0; for(int i = 1 ; i <= n ; i++) { cin >> a[i]; if(a[i] < 0) { count++; } } if(count > k) { cout << -1 << endl; } else { int sta = 1 , end = n; for(int i = 1 ; i <= n ; i++) { sta = i; if(a[i] < 0) { break; } } for(int i = n ; i >= 1 ; i--) { end = i; if(a[i] < 0) { end = i; break; } } if(sta > end || count == 0) { cout << 0 << endl; } else { int cnt = end - sta + 1; int temp = 0; int sum = 0; for(int i = sta ; i <= end ; i++) { if(a[i] < 0 && sum > 0) { b[temp++] = sum; sum = 0; } if(a[i] >= 0) { sum++; } } sort(b , b + temp , cmp); if(cnt > k) { int gg = cnt; int num = 0; for(int i = 0 ; i < temp ; i++) { gg -= b[i]; num++; if(gg <= k) break; } gg += (n - end); if(gg > k) { cout << 2 + num * 2 << endl; } else { cout << 1 + num * 2 << endl; } } else { if(k >= n - sta + 1) { cout << 1 << endl; } else { cout << 2 << endl; } } } } return 0; }