AtCoder Beginner Contest 153

AtCoder Beginner Contest 153

https://atcoder.jp/contests/abc153
这套比较简单。

E - Crested Ibis vs Monster

完全背包

#include <bits/stdc++.h>
#define ll long long

using namespace std;
const int N = 1e3 + 5, M = 1e4 + 5;
ll n, m, a[N], b[N], f[M * 2], mx;

int main () {
    cin >> m >> n;
    for (int i = 1; i <= n; i++)    cin >> a[i] >> b[i], mx = max (mx, a[i]);
    memset (f, 0x3f, sizeof f);
    f[0] = 0;
    for (int i = 1; i <= n; i++) {

    }
    
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            f[j+a[i]] = min (f[j+a[i]], f[j] + b[i]);
        }
    }

    ll ans = 1e9;
    for (int i = m; i <= m + mx; i++)   ans = min (ans, f[i]);
    cout << ans;
}

//完全背包

F - Silver Fox vs Monster

贪心。
覆盖范围转化为 \([x_i,x_i+2d]\)
然后二分最大覆盖范围,差分更新区间贡献

#include <bits/stdc++.h>
#define ll long long

using namespace std;
typedef pair<ll, ll> pii;
const int N = 2e5 + 5;
ll n, d, a, cnt, b[N]; //差分数组
pii p[N];

int main () {
    cin >> n >> d >> a;
    for (int i = 1; i <= n; i++) {
        cin >> p[i].first >> p[i].second;
        p[i].second = (p[i].second + a - 1) / a;
        // cout << p[i].second << ' ';
    }
    sort (p + 1, p + n + 1);

    for (int i = 1; i <= n; i++) {
        //找到第一个能被消去的
        b[i] += b[i-1];
        ll cur = p[i].second - b[i];
        if (cur <= 0)   continue;
        cnt += cur, b[i] += cur;
        ll l = i, r = n;
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (p[mid].first <= p[i].first + 2 * d)     l = mid;
            else    r = mid - 1;
        }
        b[l+1] -= cur;
        // cout << i << ' ' << l << endl;
        //[i,l]都-p[i].second

    }
    cout << cnt << endl;
}

//贪心把炸弹放在xi, 则覆盖[xi,xi+2d]
//差分维护改变值, 二分最大范围
//优化: 差分 + 二分
posted @ 2023-04-02 10:59  Sakana~  阅读(12)  评论(0编辑  收藏  举报