题目大意:有个人要去参加派对,一共有n场派对,每场派对需要的衣服为a[i],这个人可以同时套上多件衣服,当派对需要的衣服为a[i]时,他可以直接穿上一件a[i],也可以一件件的脱掉,直到身上的衣服为a[i]为止,问这个人最少需要穿几次衣服。
题解:
区间DP问题,定义状态dp[l][r]表示第l场派对到第r场派对共需要穿多少件衣服,该怎么转移呢?可以直接穿上所以dp[l][r]=dp[l][r-1]+1,也可以通过脱掉一定的衣服,dp[l][r]=dp[l][i]+dp[i+1][r-1],要求a[i]=a[r],即我们需要将[i+1,r-1]这几场派对的衣服给脱掉,然后将第i场派对的衣服露出来,dp[l][i]表示从第l天到第i天需要的衣服,dp[i+1][r-1]表示第i+1天到第r-1天需要的衣服,也就是我们需要脱掉的衣服。
code:
#include<bits/stdc++.h> using namespace std; const int N=100+7; int arr[N]; int dp[N][N]; int time1=0; void solve(){ int n; cin>>n; memset(dp,0,sizeof dp); for(int i=1;i<=n;i++) { cin>>arr[i]; dp[i][i]=1; } for(int i=1;i<n;i++){ if(arr[i]==arr[i+1]) dp[i][i+1]=1; else dp[i][i+1]=2; } dp[0][0]=0; for(int len=2;len<=n;len++){ for(int l=1,r=len;r<=n;r++,l++){ dp[l][r]=dp[l][r-1]+1; for(int i=l;i<=r-1;i++){ if(arr[i]==arr[r]) dp[l][r]=min(dp[l][i]+dp[i+1][r-1],dp[l][r]); } } } printf("Case %d: %d ",++time1,dp[1][n]); } int main(){ int t;cin>>t; while(t--) solve(); return 0; }