原题链接
- 题意:你有两种轮胎,雪地胎和普通轮胎。雪地胎可以在任何路况行驶,而普通轮胎只能在不下雪的时候行驶。你现在知道你的雪地胎最多能用 (k) 天。现在告诉你总天数 (n),和每天是否下雪。问你,最少要换几次轮胎,才能保证下雪天都在用雪地胎,并且雪地胎使用天数不超过 (k) 天。你初始状态是普通轮胎,结束状态无所谓。
- 题解:抽象一下模型,即给出了一条线段总长度,然后给出了线段上一些点需要覆盖,然后问,是否能用线段来覆盖全部的点,求最少的线段数量。如果线段总长 (k<cnt) 那么无法覆盖,否则一定可以。先假定一个点就是一个线段,那么初始的 (ans = cnt imes 2) 在此基础上,来合并线段,那么一定是补全间隔最小的,所以可以先把全部的间隔拿出来排个序,然后补全间隔最小的,从小到大补,补一个 (ans -= 2) 最后一段如果可以补,那么 (ans--)。
- 代码:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <vector>
using namespace std;
typedef long long ll;
const ll N = 1e6 + 99;
ll mod = 1e9 + 7;
const ll maxn = 1e7;
ll a[N];
ll in[N];
void solve() {
int n, k;
cin >> n >> k;
int top = 0;
int sum = 0;
int pre = -1;
for (int i = 1; i <= n;i ++) {
cin >> a[i];
if (a[i] < 0){
sum++;
if (pre == -1)pre = i;
else {
//if (i == 8) cout << i-pre-1 << "????";
in[++top] = i-pre-1;
pre = i;
}
}
}
sort(in + 1,in+1+top);
ll ans = 0;
if (sum > k) {
cout << -1;return;
}
ans = sum * 2;
k -= sum;
for (int i = 1; i <= top; i ++) {
//cout << in[i] << endl;
if (k >= in[i]) {
k -= in[i];ans -= 2;
}
}
if (n + 1-pre-1 <= k) {
ans--;
}
cout << ans << endl;
}
signed main() {
ll t = 1;
ios::sync_with_stdio(0);
while (t--) solve();
return 0;
}