UVA1579 俄罗斯套娃 Matryoshka(区间dp+序列dp)

Posted blog-fgy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA1579 俄罗斯套娃 Matryoshka(区间dp+序列dp)相关的知识,希望对你有一定的参考价值。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxN = 505;
int N, a[maxN], dp[maxN][maxN], MAX[maxN][maxN], MIN[maxN][maxN], f[maxN][maxN], F[maxN];
bool b[maxN], rep[maxN][maxN], flag;
inline int merge(int a, int b, int c, int d) {
    return f[b][MIN[c][d]] - f[a - 1][MIN[c][d]] + f[d][MIN[a][b]] - f[c - 1][MIN[a][b]];
}
int main() {
    while(scanf("%d", &N) != EOF) {
        flag = 0;
        memset(dp, 0x3f, sizeof(dp));
        memset(MAX, -0x3f, sizeof(MAX));
        memset(MIN, 0x3f, sizeof(MIN));
        memset(f, 0, sizeof(f));
        memset(F, 0x3f, sizeof(F));
        memset(rep, 0, sizeof(rep));
        for(int i = 1; i <= N; i++) 
            scanf("%d", &a[i]), MAX[i][i] = a[i], MIN[i][i] = a[i], dp[i][i] = 0;
        for(int i = 1; i <= N; i++) {
            for(int j = 1; j <= N; j++) {
                if(j > i) {
                    MAX[i][j] = max(a[j], MAX[i][j - 1]);
                    MIN[i][j] = min(a[j], MIN[i][j - 1]);
                }
                f[i][j] = f[i - 1][j] + (a[i] > j ? 1 : 0);
            }
        }
        for(int len = 2; len <= N; len++) {
            for(int l = 1; l + len - 1 <= N; l++) {
                int r = l + len - 1;
                for(int k = l; k <= r; k++) {
                    if(!b[a[k]]) b[a[k]] = true;
                    else{flag = true; rep[l][r] = true; break;}                    
                }
                memset(b, 0, sizeof(b));
                if(flag){flag = false; continue;}
                for(int k = l; k < r; k++)
                    dp[l][r] = min(dp[l][r], dp[l][k] + dp[k + 1][r] + merge(l, k, k + 1, r));
            }
        }
        F[0] = 0;
        for(int i = 1; i <= N; i++)
            for(int j = 0; j < i; j++)
                if(MAX[j + 1][i] == i - j && (!rep[j + 1][i]))
                    F[i] = min(F[i], F[j] + dp[j + 1][i]);
        if(F[N] >= 0x3f3f3f3f)     printf("impossible
");
        else printf("%d
", F[N]);
    }
    return 0;
}

 

以上是关于UVA1579 俄罗斯套娃 Matryoshka(区间dp+序列dp)的主要内容,如果未能解决你的问题,请参考以下文章

俄罗斯套娃的选购秘籍

套娃是俄罗斯的一种民间工艺品,大套娃里面有小套娃,

俄罗斯套娃是啥梗?

俄罗斯套娃信封问题

网络用语套娃是啥意思 网络用语套娃的意思

LeetCode——俄罗斯套娃信封问题