[LuoguP3668][USACO17OPEN]现代艺术2

Posted yeasio-nein

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LuoguP3668][USACO17OPEN]现代艺术2相关的知识,希望对你有一定的参考价值。

[LuoguP3668][USACO17OPEN]Modern Art2(Link

现在你有一块长为(N)的画布,每次可以选择一段连续的区间进行颜色填涂,新颜色会覆盖旧颜色。每一次填涂都要耗费一天时间。在所有的填涂中每一种颜色只能用1次。求将画布变为目标序列的最小天数。如果不能完成填涂那么输出(-1)

首先我们要知道填涂的方式以及什么叫做填涂不合法。

技术分享图片

上面的这个方案明显是合法的,我们先涂上“底色”(Green)然后再涂(Red)就好。

技术分享图片

上面的这个情况,你发现无论怎么涂都是不合法。那么我们找到了一个显然的规律:有交叉的颜色就不合法。

于是问题变得简单了,我们用一个栈直接记录一下花费时间就可以了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
typedef long long LL ;
const int MAXN = 100010 ;
const int MAXM = 100010 ;
int N, Line[MAXN], S[MAXN], S1[MAXN], Top, S2[MAXN], Sum ;

inline int Read() {
    int X = 0, F = 1 ; char ch = getchar() ;
    while (ch > '9' || ch < '0') F = (ch == '-' ? - 1 : 1), ch = getchar() ;
    while (ch >= '0' && ch <= '9') X=(X<<1)+(X<<3)+(ch^48), ch = getchar() ;
    return X * F ;
}

int main() {
    N = Read() ;
    for (int i = 1 ; i <= N ; i ++)  {
        Line[i] = Read() ; S2[Line[i]] = i ;
        if (! S1[Line[i]]) S1[Line[i]] = i ;
    }   S2[Line[N + 1]] = N + 1 ;
    for (int i = 0 ; i <= N + 1 ; i ++) {
        if (i == S1[Line[i]]) S[++ Top] = Line[i], Sum = max(Top, Sum) ;
        if (Line[i] != S[Top]) {
            printf("-1") ; return 0 ;
        }   if (i == S2[Line[i]]) Top -- ;
    }
    printf("%d", Sum) ;
}

以上是关于[LuoguP3668][USACO17OPEN]现代艺术2的主要内容,如果未能解决你的问题,请参考以下文章

luoguP3147 [USACO16OPEN]262144

[luoguP3146] [USACO16OPEN]248(区间DP)

[luoguP2890] [USACO07OPEN]便宜的回文Cheapest Palindrome(DP)

[luoguP2948] [USACO09OPEN]滑雪课Ski Lessons(DP)

[luoguP3606] [USACO17JAN]Building a Tall Barn建谷仓(贪心 + 线段树)

洛谷 P3670 [USACO17OPEN]Bovine Genomics S奶牛基因组(银)