首先,我还是表扬一下自己,开始独立思考了,虽然说最后的想法是错误的,但是至少已经很接近了。所以,再接再厉吧!
题意:
现在那个人要去参加一个聚会,然后总共有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]); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-19 09:34:56