题目链接:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=15381
题意:
有n个party,m种衣服,告诉你了这n个party需要穿的衣服,每次衣服脱了就不能再穿了。
问他最少需要多少套衣服。
分析:
我们想要衣服最少那么肯定要换的次数最少,就是使尽量多的场次穿一样的衣服,那么就类似这个问题了,求一个区间内有多少个括号匹配。
我们这个问题就是求区间内有多少种衣服相同
dp[i][j]表示i到j有多少种衣服相同
最后的衣服数等于n-dp[1][n].
如果第i个party 与第j个party所穿的衣服一样的话,那么dp[i][j]=max{dp[i][k]+dp[k+1][j]}+1;
否则dp[i][j]=max{dp[i][k]+dp[k+!][j]} (i<=k<j)
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 110; int a[maxn]; int dp[maxn][maxn]; int main() { int n,m,t,cas=1; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); memset(dp,0,sizeof(dp)); for(int len=2;len<=n;len++){ for(int i=1;i+len<=n+1;i++){ int j = i+len-1; for(int k=i;k<j;k++){ if(a[i]==a[j]) dp[i][j]=max(dp[i][k]+dp[k+1][j]+1,dp[i][j]); else dp[i][j]=max(dp[i][k]+dp[k+1][j],dp[i][j]); } } } printf("Case %d: %d\n",cas++,n-dp[1][n]); } return 0; }