poj2430

题目意思:一个2*b的矩形上有n头牛,现在要用k个矩形覆盖牛。问最少覆盖的面积

思路:状态压缩dp

        因为b太大,所以得先离散化

        f[i][j][k]表示前i列(有牛在的列),用了k个矩形,状态为K所用的最小面积

        情况有:1.单独放1个矩形

                   2.单独放2个矩形

                   3.由前面放的延伸过来(1个或2个)

情况多了点,写起来挺麻烦的。。

 1 /*
 2    State:Accepted
 3    Time:2013-03-19 19:26:02
 4 */
 5 #include<cstring>
 6 #include<string>
 7 #include<cstdlib>
 8 #include<cstdio>
 9 #include<cmath>
10 #include<algorithm>
11 #include<set>
12 using namespace std;
13 struct oo{  int x, y; };
14 int N, K , B ;
15 const int num[5] = {0, 1, 1, 2, 2};
16 oo  a[1500];
17 int f[1010][1010][5] , map[1500] ,p[1500],tot(0);
18 void init(){
19     scanf("%d%d%d",&N, &K, &B);
20     for (int i = 1; i <= N; ++i )
21        scanf("%d%d",&a[i].y, &a[i].x);
22 }
23 
24 int cmp(const oo a, const oo b){
25     if (a.x < b.x || a.x == b.x && a.y < b.y ) return true;
26     return false;
27 }
28 
29 void solve(){
30     sort(a + 1, a + 1 + N, cmp);
31     memset(map, 0 ,sizeof(map));
32     for (int i = 1; i <= N;  ++i){
33              if (a[i].x != a[i -1].x) ++tot;
34              map[tot]= map[tot] | 1 << a[i].y - 1;
35              p[tot] = a[i].x;
36       }
37       
38     for (int i = 0; i <= tot; ++i)
39         for (int j = 0; j <= K; ++j)
40            for (int opt = 0; opt <= 4; ++opt)
41              f[i][j][opt] = 0xfffffff;
42 
43     f[0][0][0] = 0;       
44     for (int  i = 1; i <= tot; ++i)
45          for (int j = 1; j <= K; ++j)
46              for (int opt = 1; opt <= 4; ++opt)
47                if ((opt & map[i]) >= map[i] || opt == 4){
48                      f[i][j][opt] = min(f[i-1][j][opt], f[i-1][j][4]) +  (p[i] - p[i-1]) * num[opt];
49                      if (opt == 4){
50                            f[i][j][4] = min(f[i][j][4],min(f[i-1][j-1][1], f[i-1][j-1][2]) 
51                                                        + p[i] - p[i-1] + 1);
52                      }
53                      
54                      for (int nopt = 0; nopt <= 4; ++nopt){
55                        if (opt == 4){
56                              if (j > 1) f[i][j][opt] = min(f[i-1][j-2][nopt] + 2,f[i][j][opt]) ;
57                         }  else   f[i][j][opt] = min( f[i][j][opt],f[i-1][j-1][nopt] + num[opt]);
58 
59                      }
60                }
61    /* int ans = 0xfffffff;
62      for (int  i = 1; i <= tot; ++i)
63          for (int j = 1; j <= K; ++j)
64              for (int opt = 1; opt <= 4; ++opt)
65                 if (f[i][j][opt] < 0xfffffff) printf("f[%d][%d][%d] = %d \n",i , j , opt, f[i][j][opt]);*/
66     for (int i = 0; i <= 4; ++i)
67        ans = min(f[tot][K][i] , ans);
68     printf("%d\n",ans);
69 }
70 
71 int main(){
72     freopen("poj2430.in","r",stdin);
73     freopen("poj2430.out","w",stdout);
74     init();
75     solve();
76     fclose(stdin); fclose(stdout);
77 }

 

posted on 2013-03-24 00:28  yzcstc  阅读(219)  评论(0编辑  收藏  举报