lightoj1422_区间dp

题目链接:http://lightoj.com/volume_showproblem.php?problem=1422

题意:给你n天分别要穿的衣服,可以套着穿,但是一旦脱下来就不能再穿了,问这n天要准备几件衣服。

思路:dp[i][j]为第i天到第j天要穿的最少衣服,考虑第i天,如果后面的[i+1, j]天的衣服不要管,那么dp[i][j] = dp[i + 1][j] + 1。

然后在区间[i +1, j]里面找到和第i天衣服一样的日子,尝试直到那天都不把i脱掉,

那么就变成dp[i][j] = dp[i + 1][k - 1] + dp[k][j],你可能会发现第i天不见了,其实只要把+两边换一下就好说了,就是第k天的衣服一直穿着。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cstdio>
 6 #include <vector>
 7 #include <ctime>
 8 #include <queue>
 9 #include <list>
10 #include <set>
11 #include <map>
12 using namespace std;
13 #define INF 0x3f3f3f3f
14 typedef long long LL;
15 
16 int a[110], dp[110][110];
17 int dfs(int l, int r)
18 {
19     if(dp[l][r] >= 0)
20         return dp[l][r];
21     if(l > r)
22         return 0;
23     if(l == r)
24         return 1;
25     int sum = INF;
26     for(int k = l+1; k <= r; k++)
27     {
28         if(a[l] == a[k])
29             sum = min(sum, dfs(l+1, k-1) + dfs(k, r));
30         else
31             sum = min(sum, dfs(l+1, k-1) + dfs(k, r) + 1);
32     }
33     dp[l][r] = sum;
34     return sum;
35 }
36 int main()
37 {
38     int t, n;
39     scanf("%d", &t);
40     for(int ca = 1; ca <= t; ca++)
41     {
42         scanf("%d", &n);
43         for(int i = 1; i <= n; i++)
44         {
45             scanf("%d", &a[i]);
46         }
47         memset(dp, -1, sizeof(dp));
48         printf("Case %d: %d\n", ca, dfs(1, n));
49     }
50     return 0;
51 }
View Code

 

posted @ 2016-09-27 15:49  海无泪  阅读(120)  评论(0编辑  收藏  举报