標籤:動態規劃 dp 區間dp
首先,我還是表揚一下自己,開始獨立思考了,雖然說最後的想法是錯誤的,但是至少已經很接近了。所以,再接再厲吧!
題意:
現在那個人要去參加一個聚會,然後總共有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 99999999int 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