UVA - 10559 Blocks

UVA - 1055

思路:区间dp + 记忆化搜索

dp[i][j][k] : (区间 [i,  j] 后面带上一段和 j 颜色相同的且长度为 k )的消消乐最大积分

1.消最后一段颜色和a[j]相同的

dp[i][j][k] <-- dp[i][j-1] + (k+1)^2

2.对于i <= l < j, 如果 l 和 i 的颜色相同, 那么可以把 [l+1, i-1]消掉, 那么剩下的一段就有 k+1 个和 l 相同的一段了

dp[i][j][k] <-- dp[i][l][k+1] + dp[l+1][i-1][0]

答案就是dp[1][n][0],采用记忆化搜索更方便转移

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define y1 y11
#define pi acos(-1.0)
#define LL long long
//#define mp make_pair
#define DEBUG
#define pb push_back
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdd pair<long double, long double>
#define mem(a, b) memset(a, b, sizeof(a))
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);
//head

const int N = 205;
int dp[N][N][N];
int a[N];
int dfs(int l, int r, int k) {
    if(l > r) return 0;
    if(l == r) return (k+1)*(k+1);
    if(~dp[l][r][k]) return dp[l][r][k];
    dp[l][r][k] = dfs(l, r-1, 0) + (k+1)*(k+1);
    for (int i = l; i < r; i++) {
        if(a[i] == a[r]) {
            dp[l][r][k] = max(dp[l][r][k], dfs(l, i, k+1) +  dfs(i+1, r-1, 0));
        }
    }
    return dp[l][r][k];
}
int main() {
    int T, n;
    scanf("%d", &T);
    for(int cs = 1; cs <= T; cs++) {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
        mem(dp, -1);
        printf("Case %d: %d\n", cs, dfs(1, n, 0));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/widsom/p/10326641.html
今日推荐