CodeForce 1706B. Making Towers

18 篇文章 0 订阅

题目链接

CodeForce 1706B. Making Towers
不太会做贪心的题目。

思路

记两个相邻的同色色块,之间所夹的色块数量 k k k,容易看出,

  • k k k为偶数,我们可以向左铺 k / 2 k/2 k/2块,再向右铺 k / 2 k/2 k/2块。此时tower的高度可以+1
  • 对于 k k k为奇数的情况,可以向左(或向右)铺 ( k + 1 ) / 2 (k + 1)/2 (k+1)/2块。此时我们可以:
    1. 在当前位置重新建一个新tower
    2. 或消费掉当前色块,从而继续向左铺当前颜色,从而使得后续的色块又能与先前的tower连接起来,使得其能够更大。

如果在上面所夹奇数色块的情况发生时,我们已建立出的tower高度为 h 1 h_1 h1,而从当前位置能够建立的新tower的高度 h 2 h_2 h2
那么
a n s = max ⁡ ( h 2 − 1 + h 1 , h 1 , h 2 ) ans=\max(h_2 - 1 + h_1, h_1,h_2) ans=max(h21+h1,h1,h2)
h 1 ≥ 1 , h 2 ≥ 1 h_1\ge1,h_2 \ge 1 h11h21,故 h 2 − 1 + h 1 ≥ h 1 , h 2 h_2-1+h_1 \ge h_1, h_2 h21+h1h1,h2
可见后两种情况都被涵盖在第一种情况之中,那么我们只需要尽可能让之前的塔更高就行了。
综上,我们只需要统计相邻色块之间是否相夹偶数块色块的数量,即为 a n s ans ans

#include<bits/stdc++.h>

using namespace std;
typedef long long LL;

int main() {
    int n_case;
    cin >> n_case;
    while (n_case--) {
        int n;
        cin >> n;
        vector<vector<int>> c(n + 1);
        for (int i = 0; i < n; ++i) {
            int color;
            cin >> color;
            c[color].push_back(i);
        }
        for (int i = 1; i <= n; ++i) {
            auto &g = c[i];
            int len = g.size();
            LL ans = 1;
            if (len > 1) {
                for (int j = 1; j < len; ++j)
                    if ((g[j] - g[j - 1] - 1) % 2 == 0)
                        ++ans;
            } else
                ans = len;
            printf("%lld", ans);
            if (i != n)
                printf(" ");
        }
        printf("\n");
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值