zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    html例题——简历
    求值
    c#语句实例(排大小)
    3.6语言基础笔记
    2016.3.5进制间的转换
    3.26-1
    3.23(网页)
    3.23
    3.22
    3.20
  • 原文地址:https://www.cnblogs.com/yzcstc/p/2977949.html
Copyright © 2011-2022 走看看