LightOJ 1422:Halloween Costumes(区间DP入门)

http://lightoj.com/volume_showproblem.php?problem=1422

题意:去参加派对,有n场派对,每场派对要穿第wi种衣服,可以选择外面套一件,也可以选择脱掉。问至少需要穿多少次衣服。

思路:开始学一下区间DP。学习资料

区间dp就是枚举区间的长度,然后在起点i到起点+长度j这段区间里面,用一个分割线分隔开,分为左右两边,然后通过左右两边的子问题去更新当前枚举的区间的结果。复杂度一般都为O(n^3)。

这里的题目就是一开始dp[i][i] = 1,代表初始的第i个派对需要穿1件衣服。

dp[i][j] = dp[i][k] + dp[k+1][j]。如果 wi == wj 的话,那么代表在起点穿该件衣服,终点可以脱掉之前的衣服用之前的衣服。所以答案需要-1。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define N 105
 4 #define INF 0x3f3f3f3f
 5 int w[N], dp[N][N];
 6 int main() {
 7     int t, cas = 0;
 8     scanf("%d", &t);
 9     while(t--) {
10         int n;
11         scanf("%d", &n);
12         memset(dp, INF, sizeof(dp));
13         for(int i = 1; i <= n; i++) scanf("%d", &w[i]), dp[i][i] = 1;
14         for(int len = 1; len < n; len++) {
15             for(int i = 1; i + len <= n; i++) {
16                 int j = i + len;
17                 for(int k = i; k < j; k++)
18                     if(dp[i][j] > dp[i][k] + dp[k+1][j]) dp[i][j] = dp[i][k] + dp[k+1][j];
19                 if(w[i] == w[j]) dp[i][j]--;
20             }
21         }
22         printf("Case %d: %d
", ++cas, dp[1][n]);
23     }
24     return 0;
25 }
原文地址:https://www.cnblogs.com/fightfordream/p/6445790.html