Halloween Costumes LightOJ - 1422 区间dp

Halloween Costumes LightOJ - 1422 区间dp

题目链接
题目大意:按顺序去参加舞会。每个舞会对衣服都有要求。可以连续穿好多件衣服。需要时候就脱下来,但是一旦脱下来,这件衣服就报废了。问最少需要几件衣服。
输入:
T组样例
4
1 2 1 2
输出:
3
第一天人穿1,第二天穿2,套在1外边,第三天脱2,漏出1,最后一天穿2。一共穿三次
思路:
其实只用考虑新加的衣服跟最里面的衣服的关系就可以了,如果最里面的和新加的是一样的,就不需要穿这件衣服,因为一定可以露出这件衣服。然后去枚举作为最里面的那件衣服是哪件衣服。感觉自己没有想出这道题还是因为没有想出黑字部分。

#include 
using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 110;

int dp[maxn][maxn], data[maxn];

int main()
{
    int t, n, cas = 1;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        memset(dp, 0, sizeof(dp));
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &data[i]);
        }

        for(int i = 1; i <= n; i++)
            for(int j = i; j <= n; j++)
            dp[i][j] = j - i + 1;

        for(int len = 2; len <= n; len++) //枚举区间
        {
            for(int i = 1; i <= n; i++) //枚举起点
            {
                int j = i + len - 1;
                if(j > n) break;
                dp[i][j] = dp[i][j - 1] + 1;
                for(int k = i; k < j; k++) //枚举作为最里面的衣服
                {
                    if(data[j] == data[k]) //新加的和最里面的一样
                    {
                        dp[i][j] = min(dp[i][j], dp[i][k - 1] + dp[k + 1][j]);
                    }

                }
            }
        }
        printf("Case %d: %d\n", cas++, dp[1][n]);
    }
}

你可能感兴趣的:(区间dp)