dp之区间:Light oj 1422 Halloween Costumes

http://lightoj.com/volume_showproblem.php?problem=1422

题意:给你n天需要穿的衣服的样式,每次可以套着穿衣服,脱掉的衣服就不能再穿了,问至少要带多少条衣服才能参加所有宴会

思路:我们从后往前推导,dp[i][j]代表从区间i到区间j最少的穿衣数量,那么在dp[i][j]这个状态的穿衣数,就要等于dp[i+1][j]+1;也就是说,首先在不考虑它后面是否有一天要穿相同的衣服的情况下,它肯定会比区间i+1到j的衣服多出一件;

然后,再考虑在这个区间范围,是否有一天要穿相同的衣服,i<k<=j,如果有第k天衣服和第i天的衣服是一样的,那么就要比较如果第i天不穿1件衣服与第i天穿上1件衣服;

首先,第i天穿上一件衣服的结果已经得出,那么我们只需比较不穿衣服,那么就是dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j]);

在处理状态的时候,是从n往1推导的状态.......

 

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int dp[105][105],a[105];
int min(int x,int y)
{
	if(x>y)
	return y;
	else
	return x;
}
int main()
{
	int text,x4=0;
	scanf("%d",&text);
	while(text--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
		memset(dp,0,sizeof(dp));
		for(int i=1;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+1;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",++x4,dp[1][n]);
	}
	return 0;
} 

 

 

 

posted @ 2013-08-01 11:48  紫忆  阅读(1118)  评论(0编辑  收藏  举报