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