其他分享
首页 > 其他分享> > Lightoj1422——区间dp经典题

Lightoj1422——区间dp经典题

作者:互联网

题目链接:http://lightoj.com/volume_showproblem.php?problem=1422

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

题目翻译:

盖普有一个非常繁忙的周末在他面前。因为,下周末是万圣节,他计划参加尽可能多的聚会。由于是万圣节,这些派对都是服装派对,Gappu总是选择他的服装,这样它与他的朋友融合,也就是说,当他参加聚会,由他的漫画迷的朋友安排,他会去与超人的服装,但当晚会安排比赛时,他会穿上"中国邮递员"的服装。‎

‎由于他将在万圣节之夜参加一些聚会,并相应地穿戏服,他将多次更换服装。所以,为了让事情变得简单一点,他可以把服装一个接一个(也就是说,他可以穿制服的邮递员,超人服装)。在每次聚会之前,他都可以脱下一些服装,或者穿一件新衣服。也就是说,如果他穿着邮递制服超过超人服装,并想去参加一个聚会的超人服装,他可以脱下邮递制服,或者他可以穿新的超人制服。但是,请记住,Gappu不喜欢穿礼服而不先清洗他们,所以,脱下邮递制服后,他不能再次使用在万圣节晚上,如果他需要邮递员服装再次,他将不得不使用一个新的。他可以脱下任意数量的服装,如果他脱下k的服装,这将是最后的k(‎‎例如,如果他穿服装A之前的服装B,‎‎脱下A,首先他必须‎‎删除B)。 ‎‎ ‎‎ ‎

‎鉴于派对和服装,找到在万圣节之夜Gappu将需要的最低数量的服装。‎

‎输入‎

‎输入以整数‎‎T‎‎(=‎‎200)‎‎开头,表示测试用例的数量。‎

‎每个事例以一条包含整数‎‎N(1 = N = 100)‎‎的行开头,表示参与方数。下一行包含‎‎N‎‎整数,其中‎‎ith‎‎整数‎‎c‎‎i‎‎ ‎‎ ‎‎(1 = c‎‎i‎‎ = 100)‎‎表示他将在第‎‎一‎‎方中穿的服装。他先参加第一方,然后是第2方,等等。

输入

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

输出

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

 

很好的一道区间dp入门题

状态:dp[i][j]表示从区间i到区间j所需服装的最小数量

转移方程:dp[i][j]=dp[i][j-1]+1;只考虑第j天,前面的i到j-1天不用管,

dp[i][j]=min{dp[i][k]+dp[k+1][j-1]}(a[k]==a[j]) 在区间i到j-1天里面找到与第j天能穿相同的衣服的日子,直到第k天不脱下来第j天的衣服。

也可以正着推,效果都一样。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[105],dp[105][105];
int main(int argc, char** argv) {
	int T,n;
	cin>>T;
	for(int ncase = 1;ncase<=T;++ncase){
		cin>>n;
		for(int i = 1;i<=n;++i){
			cin>>a[i];
			dp[i][i]=1;
		} 
		for(int len = 1;len<n;++len){
			for(int i=1;i+len<=n;++i){
				int j=i+len;
				dp[i][j]=dp[i][j-1]+1;
				for(int k = i;k<=j-1;++k){
					if(a[k]==a[j]){
						dp[i][j]=min(dp[i][k]+dp[k+1][j-1],dp[i][j]);
					}
				}
			}
		}
		printf("Case %d: %d\n",ncase,dp[1][n]);
	}
	return 0;
}

 

标签:服装,派对,Lightoj1422,int,超人,万圣节,经典,dp
来源: https://blog.csdn.net/qq_43472263/article/details/98317489