Halloween Costumes LightOJ - 1422(区间dp)

题目

小灰灰参加圣诞节的一些派对,并且需要穿上对应派对的衣服,所以他需要多次换衣服,为了方便,他可以选择脱掉一些衣服或者穿上新衣服如果他先穿A衣服,又穿上B衣服,再穿一件C衣服,如果他想让最外面的衣服是A,他可以选择直接穿一件A,或者先把C脱掉,再把B脱掉)。

输入
第一行输入一个T,表示测试案例的数量 T<=200 N和a[i]<=100
接下来一行输入一个N,表示派对个数,
接下来一行n个数,表示第i个派对他会穿着a[i]的衣服参加这场派对(派对的前后顺序不可调换)

输出
对于每个测试案例,输出“Case i: ”加所需服装的最小数量。
案例输入
2
4
1 2 1 2
7
1 2 1 1 3 2 1

案例输出
Case 1: 3
Case 2: 4

解释

dp[i][j]代表区间i~j最少的穿衣数量,
对于第j件衣服可选择穿新的与不穿(脱去衣服以露出与第j件衣服相同的衣服), 穿就是dp[i][j] = dp[i][j-1]+1;
不穿dp[i][j] = min(dp[i][k] + dp[k+1][j-1]); k的条件为在i <= k <= j-1 && a[k] == a[j]
i到k的最少衣服数量加上k后面的衣服的最少衣服数量相加等于不穿的最少衣服数量。

#include <cstdio>
#include <algorithm>
int const maxn = 102;
using namespace std;
int dp[maxn][maxn];
int a[maxn];
int main(){
	int t;
	int n, i, j, k;
	int cont = 1;
	scanf("%d", &t);
	while(t--){
		scanf("%d", &n);
		for( i = 1; i <= n; i++){
			scanf("%d", a+i);
		}
		for(i = n; i >= 1; i--){
			dp[i][i] = 1;
			for(j = i+1; j <= n; j++){
				dp[i][j] = dp[i][j-1]+1;
				for(k = i; k < j; k++){
					if(a[k] == a[j]){
						dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j-1]);
					}
				}
			}
		}
		printf("Case %d: %d\n", cont++,dp[1][n]);
	}
	return 0;
}
发布了52 篇原创文章 · 获赞 2 · 访问量 873

猜你喜欢

转载自blog.csdn.net/qq_44714572/article/details/103037895