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;

} 

 

 

 

你可能感兴趣的:(OS)