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]
//差分维护改变值, 二分最大范围
//优化: 差分 + 二分