题意:给你n天分别要穿的衣服,可以套着穿,但是一旦脱下来就不能再穿了,问这n天要准备几件衣服。
第一次做区间DP,看着题解们想了很久才想通orz...
dp[i][j]为第i天到第j天要穿的最少衣服,考虑第i天,如果后面的[i+1, j]天的衣服不要管,那么dp[i][j] = dp[i + 1][j] + 1。
然后在区间[i +1, j]里面找到和第i天衣服一样的日子,尝试直到那天都不把i脱掉,
那么就变成dp[i][j] = dp[i + 1][k - 1] + dp[k][j],你可能会发现第i天不见了,其实只要把+两边换一下就好说了,就是第k天的衣服一直穿着。
代码:
/*
* Author: illuz <iilluzen[at]gmail.com>
* Blog: http://blog.csdn.net/hcbbt
* File: loj1422.cpp
* Create Date: 2013-11-11 13:53:33
* Descripton: invertel dp
*/
#include <cstdio>
#include <cstring>
#define min(a, b) ((a) < (b) ? (a) : (b))
const int MAXN = 110;
int dp[MAXN][MAXN], a[MAXN];
int n, t, cas;
int main() {
scanf("%d", &t);
for (cas = 0; cas < t; cas++) {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 0; i <= n; i++)
for (int j = i; j <= n; j++)
dp[i][j] = j - i + 1;
for (int i = n - 1; i >= 1; i--)
for (int j = i; j <= n; j++) {
dp[i][j] = dp[i + 1][j] + 1;
for (int k = i + 1; k <= j; k++)
if (a[k] == a[i])
dp[i][j] = min(dp[i][j], dp[i + 1][k - 1] + dp[k][j]);
}
printf("Case %d: %d\n", cas + 1, dp[1][n]);
}
return 0;
}