奶牛晒衣服
开个堆,记录个时间,每次抠出来堆顶减去 b 再扔回去就做完了。
read(n, a, b);
rep(i, 1, n) read(h[i]);
priority_queue<int> q;
rep(i, 1, n) q.push(h[i]);
int t = 0;
while (q.top() > t * a) {
t++;
int x = q.top();
q.pop();
// printf("x=%d\n",x);
x -= b;
q.push(x);
}
printf("%d", t);
雷达装置
对于每个建筑物,解方程找出能探测到他的最左和最右端点,问题转化为最小区间点覆盖问题。
按 右 端 点 排 序! ! !
按 右 端 点 排 序! ! !
按 右 端 点 排 序! ! !
畜栏预定
按左端点排序,依次扔到堆里,堆里按右端点开小根堆,然后贪心即可。
荷马史诗
哈夫曼树模板。
因为哈夫曼树是从底层往根建的,所以首先你要把他补成一颗完全 k 叉树,这样保证了最优性质。
#define int long long
struct qwq {
int h, w;
bool operator<(const qwq &x) const {
if (w == x.w)
return h > x.h;
return w > x.w;
}
};
priority_queue<qwq> q;
int n, k;
signed main() {
read(n, k);
rep(i, 1, n) {
int x;
read(x);
q.push({ 1, x });
}
while ((q.size() - 1) % (k - 1)) q.push({ 1, 0 });
int ans = 0;
while (q.size() >= k) {
int w = 0, h = -1;
rep(i, 1, k) {
auto it = q.top();
q.pop();
w += it.w;
h = max(h, it.h);
}
ans += w;
q.push({ h + 1, w });
}
printf("%lld\n%lld", ans, q.top().h - 1);
}
排队接水
贪心的想,慢的人往后扔,一定最优,一遍sort即可。
砍树问题
题面很丑陋。
但其实 \(h[i] = min(p[i] - p[left(i)],p[right(i)] - p[i])\) 答案就是 \(\sum {(a[i] - h[i])}\)。
出栈问题
维护一个后缀最大值,然后贪心的看,后面有比他大的,就压进来,否则弹出去。
仙人之环
仙人掌,所以可以 dfs 判环。
那么首先断开非环边一定可以增加连通块,断完还有剩余的,就考虑按环从小到大贪心断了。
const int N = 4e6 + 5;
int n, m, k, kk, u, v, tot, ans, num, d[N], st[N];
vector<int> g[N];
void dfs(int u, int fa) {
d[u] = d[fa] + 1;
for (int v : g[u]) {
if (v == fa)
continue;
if (!d[v])
dfs(v, u);
else if (d[v] < d[u]) {
if (d[u] - d[v] > 1)
st[++tot] = d[u] - d[v] + 1, num += d[u] - d[v] + 1;
}
}
}
signed main() {
// freopen("c.in","r",stdin);freopen("c.out","w",stdout);
read(n, m, k);
rep(i, 1, m) {
read(u, v);
g[u].push_back(v);
g[v].push_back(u);
}
rep(i, 1, n) if (!d[i])++ ans, dfs(i, 0);
if (k <= m - num)
return printf("%d", k + ans), 0;
sort(st + 1, st + 1 + tot);
k -= m - num, ans += m - num;
rrep(i, tot, 1) {
if (k >= st[i])
k -= st[i], ans += st[i] - 1;
else {
ans += k - 1;
printf("%d\n", ans);
break;
}
}
}
标签:int,YBTOJ,rep,read,ans,push,合集,贪心
From: https://www.cnblogs.com/wsxxs/p/16623953.html