区间DP LightOJ 1422 Halloween Costumes

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

做的第一道区间DP的题目,试水。

参考解题报告:

http://www.cnblogs.com/ziyi--caolu/p/3236035.html

http://blog.csdn.net/hcbbt/article/details/15478095

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 <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <queue>
 7 #include <set>
 8 #include <map>
 9 #include <cmath>
10 #include <cstdlib>
11 
12 #define rep(i,a,n) for(int i = a;i <= n;i++)
13 #define per(i,n,a) for(int i = n;i>=a;i--)
14 #define pb push_back
15 #define VI vector<int>
16 #define QI queue<int>
17 #define logM(N) log10(N)/log10(M)
18 #define eps 1e-8
19 
20 typedef long long ll;
21 
22 using namespace std;
23 
24 int main()
25 {
26 #ifndef ONLINE_JUDGE
27     freopen("in.txt","r",stdin);
28     //freopen("out.txt","w",stdout);
29 #endif
30     int n,_;
31     scanf("%d",&n);
32     _ = 0;
33     int a[100 + 10] = {};
34     int dp[100 + 10][100 + 10] = {};
35     int t;
36     while(n--){
37         scanf("%d",&t);
38         rep(i,1,t+1){
39             rep(j,1,t+1){
40                 dp[i][j] = 0;
41             }
42         }
43         rep(i,1,t){
44             scanf("%d",&a[i]);
45         }
46         rep(i,0,t){
47             rep(j,i,t){
48                 dp[i][j] = 1;
49             }
50         }
51         per(i,t,1){
52             rep(j,i,t){
53                 dp[i][j] = dp[i+1][j] +1;
54                 rep(k,i+1,j){
55                     if(a[i] == a[k]){
56                         dp[i][j] = min(dp[i][j],dp[i+1][k-1]+dp[k][j]);
57                     }
58                 }
59             }
60         }
61         printf("Case %d: %d\n",++_,dp[1][t]);
62     } 
63     return 0;
64 }
View Code

 

posted @ 2016-03-03 20:17  syuritsu  阅读(153)  评论(0编辑  收藏  举报