Halloween Costumes LightOJ - 1422 区间dp

题解

题目大意 一个人参加舞会 第i个舞会需要穿着a[i]颜色的衣服 他可以同时穿着多件衣服到时候再脱掉 但是脱掉的衣服不能在穿上 问最少需要多少衣服

使用区间dp求解 d[i][j]表示从i到j区间的舞会需要的最少衣服数量 考虑
单独一个舞会需要的数量为1
如果一个区间d[i][j] a[i]==a[j]也就是第一场舞会的和最后一场的衣服一样则d[i][j]一定等于d[i][j - 1]因为最后一个一定能穿第一场的衣服 第一场的衣服全程也不会脱掉 因为他前面没衣服了脱掉无意义 即d[i][j] = d[i][j - 1]
最后遍历区间中间点合并区间d[i][j] = min(d[i][j], d[i][k] + d[k + 1][j])

AC代码

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
const int MAXN = 110;
int a[MAXN];
int d[MAXN][MAXN];

int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	int T;
	cin >> T;
	for (int ti = 1; ti <= T; ti++)
	{
		int N;
		cin >> N;
		for (int i = 1; i <= N; i++)
			scanf("%d", &a[i]);
		memset(d, 0x3f, sizeof(d));
		for (int i = 1; i <= N; i++)
			d[i][i] = 1; //单个为1
		for (int l = 2; l <= N; l++)
			for (int i = 1; i + l - 1 <= N; i++)
			{
				int j = i + l - 1;
				if (a[i] == a[j]) //区间前后相等 最后一个一定不会造成贡献
					d[i][j] = d[i][j - 1]; //从小区间转移过来 第一件不可能脱掉 最后一个肯定可以用第一件
				for (int k = i; k < j; k++) //合并区间
					d[i][j] = min(d[i][j], d[i][k] + d[k + 1][j]);
			}
		printf("Case %d: %d\n", ti, d[1][N]);
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/CaprYang/article/details/85222962