POJ 1390 Blocks - 顏色段消除的最大分數 三維DP

題目鏈接:http://poj.org/problem?id=1390&tdsourcetag=s_pctim_aiomsg
題目大意:一個積木遊戲,有連續的n個方塊。相同顏色的方塊連續方塊可以消除。如果該段由k個積木組成。得分爲k*k。在這裏插入圖片描述
在這裏插入圖片描述在這裏插入圖片描述
a[i],b[i]a[i]dp[i][j][k]:[i,j]jka[j]dp[i][j][k]=dp[i][j1][0]+(b[j]+k)(b[j]+k) \begin{array}{l} 我們首先把相同顏色的積木合併成一個塊a[i],用b[i]表示a[i]有多少個積木。\\\\ 我們用dp[i][j][k]:表示段[i,j]並且j的右邊有k個和a[j]顏色相同的積木能獲得的最大得分。\\\\ 考慮轉移:dp[i][j][k]=dp[i][j-1][0]+(b[j]+k)*(b[j]+k) \end{array}
在這裏插入圖片描述
[i,j1]a[j]a[r]dp[i][j][k]=dp[i][r][b[j]+k]+dp[r+1][j1][0] 還有一種轉移,在[i, j-1]種如果有和a[j]顏色相同的塊a[r]:\\\\ dp[i][j][k]=dp[i][r][b[j]+k]+dp[r+1][j-1][0]
在這裏插入圖片描述

#include  <bits/stdc++.h>
#define LL long long
using namespace std;

int a[205], b[205], len[205], f[205][205][205];

int DP(int l, int r, int k){
    if(r<l) return 0;
    if(f[l][r][k]!=-1) return f[l][r][k];
    int ans=DP(l, r-1, 0)+(len[r]+k)*(len[r]+k);
    for(int i=l; i<r; i++){
        if(a[i]==a[r]){
            ans=max(ans, DP(l, i, len[r]+k)+DP(i+1, r-1, 0));
        }
    }
    return f[l][r][k]=ans;
}

int main() {

    int t, T=1; scanf("%d", &t);
    while(t--){
        memset(f, -1, sizeof(f));
        memset(len, 0, sizeof(len));
        int n; scanf("%d", &n);
        for(int i=1; i<=n; i++){
            scanf("%d", &b[i]);
        }
        int tot=1;
        a[tot]=b[1], len[1]=1;
        for(int i=2; i<=n; i++){
            if(b[i]!=b[i-1]){
                a[++tot]=b[i]; len[tot]=1;
            }
            else{
                len[tot]++;
            }
        }

        printf("Case %d: %d\n", T++, DP(1, tot, 0));
    }

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章