题意:
n场按顺序排列的聚会,不同种类的聚会穿不同的衣服,人可套多件衣服,但看起来是最外面的衣服。穿1件衣服cost为1,脱衣服没有cost。问参加n场聚会的最小cost。1 <= n <= 100。
题解:
1.dp[i][j]表示[i , j]区间内聚会最小cost。
2.假如第j场需要穿衣服,dp[i][j] = dp[i][j - 1] + 1。假如第j场与第j-1场相同,则第j场不用穿衣服,dp[i][j] = dp[i][j - 1] 。
假如第k场与第j场衣服相同,dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k + 1][j - 1])。i <= k <= j - 2。
3.注意初始化。区间大小不同,初始化的内容不同。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 105
#define inf 0x3f3f3f3f
using namespace std ;
int main()
{
int i , j , k , d , p ;
int t , n ;
int a[N] ;
int dp[N][N] ;
scanf("%d" , &t) ;
for(p = 1 ; p <= t ; p ++)
{
scanf("%d" , &n) ;
for(i = 1 ; i <= n ; i ++)
scanf("%d" , &a[i]) ;
memset(dp , inf , sizeof(dp)) ;
for(i = 1 ; i <= n ; i ++)
dp[i][i] = 1 ;
for(i = 1 ; i <= n - 1 ; i ++)
if(a[i] == a[i + 1])
dp[i][i + 1] = 1 ;
else
dp[i][i + 1] = 2 ;
for(d = 2 ; d <= n - 1 ; d ++)
for(i = 1 ; i + d <= n ; i ++)
{
j = i + d ;
if(a[j - 1] == a[j])
dp[i][j] = dp[i][j - 1] ;
else
dp[i][j] = dp[i][j - 1] + 1 ;
for(k = i ; k <= j - 2 ; k ++)
if(a[k] == a[j])
dp[i][j] = min(dp[i][j] , dp[i][k] + dp[k + 1][j - 1]) ;
}
printf("Case %d: %d\n" , p , dp[1][n]) ;
}
}