LightOJ 1422 区间dp

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27130

万圣节来了,Gappu 需要挨个参加 N 个聚会,聚会需要装扮成一些类似于 Superman 一样的角色,Gappu 需要准备足够的衣服,他可以在一件衣服外面套一件一份,如果之后他需要用到穿在里面的衣服就可以脱去外面的衣服,但 Gappu 有洁癖,对于脱去的衣服,他不再想穿了,问你 Gappu 最多需要准备多少件衣服。

对于区间(l, r) <!--第l个聚会到第r个聚会--> 需要准备多少件衣服?

如果第l个聚会的衣服只在第l个聚会使用的话

DP(l, r) = DP(l+1, r) + 1;

如果区间(l+1, r)中存在聚会k和聚会l使用的衣服一样的话,Gappu 课以脱去外面的衣服,即和第l个聚会使用同一件衣服,

DP(l, r) = DP(l+1, k-1) + DP(k, r);

求最小的DP(0, n-1)就可以。

#include <cstring>
#include <iostream>
using namespace std;

int n;
int a[105];
int dp[105][105];

int DP (int l, int r) {

    if (dp[l][r] != -1) { return dp[l][r]; } 

    if (l > r) { return dp[l][r] = 0; }

    if (l == r) { return dp[l][r] = 1; }

    int tmp = DP(l+1, r) + 1;

    for (int k=l+1; k<=r; k++) {// cout << "*";
        if (a[l] == a[k]) {
            tmp = min (tmp, DP(l+1, k-1) + DP(k, r));
        }
    }

    return dp[l][r] = tmp;
}

int main () {
    int T;
    cin >> T;
    for (int i_case=1; i_case<=T; i_case++) {
        cin >> n;
        for (int i=0; i<n; i++) {
            cin >> a[i];
        }

        memset(dp, -1, sizeof(dp));

        DP(0, n-1);

        cout << "Case " << i_case << ": ";
        cout << dp[0][n-1] << endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/xuelanghu/p/4509359.html