LightOJ 1422 Halloween Costumes 区间DP

题意:给你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;
}


你可能感兴趣的:(dp,ACM)