首先,我还是表扬一下自己,开始独立思考了,虽然说最后的想法是错误的,但是至少已经很接近了。所以,再接再厉吧!
题意:
现在那个人要去参加一个聚会,然后总共有n天,每天所要求穿的服饰的序号分别为c[i]。
这个人可以一次性穿上1件衣服,或者一次性脱下任意多件衣服。当然也可以在衣服外面套衣服。
并且如果这件衣服已经被脱下的话,那么它下次不能再次被穿上,如果我们还需要这件衣服的话,那么我们就只能重新再去买另外一件了。
最后问你,如果要参加完所有的派对,那么他所需要的最少的衣服数量是多少。
比如说第一个样例:
4
1 2 1 2
我们只需要先穿上1,然后再穿上2,再脱掉1,然后此时没有2的衣服了,所以我们还需要一件2的衣服,所以最后总共是需要3件衣服。思路:
这题主要的难点是在于判断什么时候可以利用还存在的衣服。
定义dp[i][j]为i~j区间内所需要的最少衣服的数量。
感觉下面的思路很巧妙:
1)dp[i][i]=1,这是初始化dp
2)dp[i][j]=dp[i][j-1],当c[i]==c[j]的时候,那么我们就只需要j前面的数量就好了
3)当c[i]==c[k]时,dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); 注意这里是dp[i][k],因为不算k的区间是包含在i~k里的。这里的目的就是相当于再缩小下dp[s][e]
推荐几个好懂的博客:http://www.cnblogs.com/neopenx/p/4050003.html http://www.cnblogs.com/kuangbin/archive/2013/04/29/3051392.html
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 111
#define inf 99999999
int c[maxn];
int dp[maxn][maxn];
int main(){
int T,j=1;
scanf("%d",&T);
while(T--){
memset(dp,0,sizeof(dp));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
dp[i][i]=1;
}
for(int len=2;len<=n;len++){
for(int s=1;s<=n-len+1;s++){
int e=s+len-1;
dp[s][e]=inf;
if(c[s]==c[e]) dp[s][e]=dp[s][e-1];
for(int k=s;k<e;k++){
if(c[s]==c[k]) dp[s][e]=min(dp[s][e],dp[s][k]+dp[k+1][e]); //!!!
}
}
}
printf("Case %d: %d\n",j++,dp[1][n]);
}
}版权声明:本文为博主原创文章,未经博主允许不得转载。
LightOJ(1422)——Halloween Costumes
原文地址:http://blog.csdn.net/acmer_hades/article/details/48055581