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)的主要内容,如果未能解决你的问题,请参考以下文章