CF747D Winter Is Coming

原题链接

  • 题意:你有两种轮胎,雪地胎和普通轮胎。雪地胎可以在任何路况行驶,而普通轮胎只能在不下雪的时候行驶。你现在知道你的雪地胎最多能用 \(k\) 天。现在告诉你总天数 \(n\),和每天是否下雪。问你,最少要换几次轮胎,才能保证下雪天都在用雪地胎,并且雪地胎使用天数不超过 \(k\) 天。你初始状态是普通轮胎,结束状态无所谓。
  • 题解:抽象一下模型,即给出了一条线段总长度,然后给出了线段上一些点需要覆盖,然后问,是否能用线段来覆盖全部的点,求最少的线段数量。如果线段总长 \(k<cnt\) 那么无法覆盖,否则一定可以。先假定一个点就是一个线段,那么初始的 \(ans = cnt\times 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;
}
posted @ 2021-04-01 15:12  u_yan  阅读(55)  评论(0编辑  收藏  举报