给定n个派对,参加每个派对规定需要某一种衣服,一个人可以在穿多件衣服,每次参加派对可以选择穿一件新的或者脱掉当前的衣服直到符合当前派对的衣服
比较裸的区间dp
对于dp[i][j]代表区间(I,j)需要的最小衣服数目
同时我们可以发现我们每次状态转移只取决于当前区间内部是否存在和末尾状态相同的衣服
另外 dp[i][j]的当前衣服颜色就是num[j]
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <string.h>
#include <cctype>
#include <cstdlib>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#define sp system("pause")
using namespace std;
typedef long long ll;
typedef pair<int, double> pii;
const int MAXN = 105;
int dp[MAXN][MAXN];
int num[MAXN];
int main()
{
int T;
cin >> T;
int cas = 1;
while (T--)
{
int n;
cin >> n;
for (int i = 0; i < MAXN; i++)for (int j = 0; j < MAXN; j++)dp[i][j] = 200;
for (int i = 1; i <= n; i++)scanf("%d", &num[i]), dp[i][i] = 1;
for (int j = 2; j <= n; j++)
{
for (int i = 1; i <= n; i++)
{
for (int k = i; k <= n; k++)
{
if (num[i+j-1] == num[k])dp[i][i + j - 1] = min(dp[i][i + j - 1], dp[i][k] + dp[k + 1][i + j - 1] - 1);
else dp[i][i + j - 1] = min(dp[i][i + j - 1], dp[i][k] + dp[k + 1][i + j - 1]);
}
}
}
printf("Case %d: %d\n", cas++, dp[1][n]);
}
}