http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1422
dp[i][j]代表从i到j派对最少几套衣服 转移方程 dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j])
注意不能写成 dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k+1][j]+1) 因为这样就等于派对i穿的衣服在派对k结束后立刻脱掉 但是后续派对有可能也需要这套衣服
using namespace std;
const int maxn=1e2+10;
int dp[maxn][maxn];
int ary[maxn];
int n;
int main()
{
int t,cas,l,i,j,k;
scanf("%d",&t);
for(cas=1;cas<=t;cas++){
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&ary[i]);
}
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++){
dp[i][i]=1;
}
for(l=2;l<=n;l++){
for(i=1;i+l-1<=n;i++){
j=i+l-1;
dp[i][j]=dp[i+1][j]+1;
for(k=i+1;k<=j;k++){
if(ary[i]==ary[k]){
//dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k+1][j]+1);
dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j]);
}
}
}
}
printf("Case %d: %d\n",cas,dp[1][n]);
}
return 0;
}