CodeForces1400E 分治

题意

蕊蕊最近在玩一个消消乐游戏,这个消消乐的规则和一般的消消乐不同,玩法很简单只有两种操作:

选取一个相连的块,将这个块的最底部一行方块消去,上面的部分随之落下
选取一列,直接消去
如果一个区间内每一列的方块数打都大于0,则称这个区间是一个相连的块,显然任何相连的块的子区间也是一个相连的块
现在告诉你每一列的高度,你要帮助蕊蕊在最少的操作内将所有方块消去

解法

将连通的一段序列称为一个“元”,一个元可以通过两种方式消除掉

  • 进行n次操作2,暴力删除
  • 进行min{a[l] ~ a[r]} 次的操作1,消除最低高度的块,将一个元划分为多个元
    划分出来的元可以递归解决

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5010;
int N;
const int INF = 0x3f3f3f3f;
int a[maxn];
int solve(int l, int r, int h, bool flag) {
    if(l > r) {
        return 0;
    }
    int m = INF;
    for(int i = l; i <= r; i ++) m = min(m, a[i]);
    m -= h;
    if(!m && !flag) return 0;
    int ans = m;
    int la = l;
    for(int i = l ; i <= r; i ++) {
        if(a[i] - h - m == 0) {
            ans += solve(la, i - 1, h + m, false);
            la = i + 1;
        }
    }
    ans += solve(la, r, h + m,false);
    return min(r - l + 1, ans);
}
int main() {
    scanf("%d", &N);
    for(int i = 1; i <= N ; i ++) {
        scanf("%d",&a[i]);
    }
    printf("%d\n",solve(1,N,0,true));

    return 0;
}
posted @ 2020-10-02 17:15  Hugh_Locke  阅读(157)  评论(0编辑  收藏  举报