zoukankan      html  css  js  c++  java
  • poj2430 Lazy Cows ****

      1 //参见 http://hi.baidu.com/billdu/blog/item/6315841769e6905ff3de325e.html (有图有真相...)
    2 //...
    3 //
    4 //dp[i][j][k]表示到达第i列,已经建设好了j个围栏,最后一列状态是k的情况下框住的最小面积
    5 //
    6 //另外, 我这个代码是 顺推(按黑书的分类),也就是基于当前状态,遍历之前的能得到这个当前状态的状态,取最佳值
    7 //而参考的那个是 逆推, 也就是基于当前状态,计算能由这个“当前状态”推出的“下一状态”,如果这样推能使“下一状态”的值更佳
    8 //则更新“下一状态”的值。
    9 //
    10 //另外还有一道类似的题(黑书的DP练习题:艺术馆的火灾 P121。。 ) 思路完全一样
    11 // 参见 http://blog.tomtung.com/2007/05/museum-fire/ (按上面的分类,其采用的算法也属于 逆推)
    12
    13 #include <cstdio>
    14 #include <algorithm>
    15 #include <fstream>
    16 #include <iostream>
    17 using namespace std;
    18
    19 const int maxb = 15000000 + 5;
    20 const int maxn = 1000 + 5;
    21 const int maxk = 1000 + 5;
    22 const int inf = 100000000;
    23
    24 //dis[i] :用于离散化,第i个有牛的列的真实列数
    25 int n, k, b, dis[maxn];
    26 //dp[i][j][k]; sta[i]:第i个实际列的牛的情况:1:只第一排有牛; 2:只第二排有牛; 3:两排都有牛:(与dp的k相同)
    27 int dp[maxn][maxk][5], sta[maxb] = {};
    28
    29 struct SCow{
    30 int r, c;
    31 };
    32 SCow cow[maxn];
    33
    34 //
    35 int inline min(int a1, int a2, int a3 = inf, int a4 = inf, int a5 = inf){
    36 int min = a1;
    37 if(min > a2) min = a2;
    38 if(min > a3) min = a3;
    39 if(min > a4) min = a4;
    40 if(min > a5) min = a5;
    41
    42 return min;
    43 }
    44
    45 /*
    46 //
    47 int uniqueArray(int *a, int size){
    48 int i = 0, j = 1;
    49 while(j < size){
    50 if(a[i] != a[j])
    51 a[++i] = a[j];
    52 j++;
    53 }
    54
    55 return i+1;
    56 }
    57 */
    58
    59
    60 //dp[i][co][1..4]的最小值
    61 int inline lastMin(int i, int co){
    62 if(co <= 0) return inf;
    63
    64 int min = inf;
    65 for(int j=1; j<5; j++){
    66 if(min > dp[i][co][j])
    67 min = dp[i][co][j];
    68 }
    69 return min;
    70 }
    71
    72
    73
    74 int main(){
    75 scanf("%d%d%d", &n, &k, &b);
    76
    77 //输入
    78 for(int i=0; i<n; i++){
    79 scanf("%d%d", &cow[i].r, &cow[i].c);
    80 dis[i] = cow[i].c; //dis
    81 sta[cow[i].c] += cow[i].r; //记录牛状态
    82 }
    83
    84 //unique dis[]
    85 sort(dis, dis+n);
    86 //int newSize = uniqueArray(dis, n);
    87 int *a = unique(dis, dis+n);
    88 int newSize = a - dis;
    89
    90 //初始化
    91 for(int i=0; i<=k; i++)
    92 for(int j=0; j<5; j++)
    93 dp[0][i][j] = inf;
    94 if(sta[dis[0]] == 2) dp[0][1][2] = 1;
    95 else if(sta[dis[0]] == 1) dp[0][1][1] = 1;
    96 dp[0][2][3] = 2;
    97 dp[0][1][4] = 2;
    98
    99
    100 //计算dp[i][j][1..4]
    101 int tmpLastMin;
    102 for(int i=1; i<newSize; i++){
    103 for(int co=1; co<=k; co++){
    104 //1
    105 dp[i][co][1] = dp[i-1][co][1] + dis[i] - dis[i-1];
    106 if(dp[i][co][1] > dp[i-1][co][3] + dis[i] - dis[i-1])
    107 dp[i][co][1] = dp[i-1][co][3] + dis[i] - dis[i-1];
    108
    109 tmpLastMin = lastMin(i-1, co-1);
    110 if(dp[i][co][1] > tmpLastMin + 1)
    111 dp[i][co][1] = tmpLastMin + 1;
    112 if(sta[dis[i]] != 1) //不能把该列的牛盖住, =inf
    113 dp[i][co][1] = inf;
    114
    115 //2
    116 dp[i][co][2] = dp[i-1][co][2] + dis[i] - dis[i-1];
    117 if(dp[i][co][2] > dp[i-1][co][3] + dis[i] - dis[i-1])
    118 dp[i][co][2] = dp[i-1][co][3] + dis[i] - dis[i-1];
    119 if(dp[i][co][2] > tmpLastMin + 1)
    120 dp[i][co][2] = tmpLastMin + 1;
    121 if(sta[dis[i]] != 2) dp[i][co][2] = inf; //不能把该列的牛盖住, =inf
    122
    123 //3
    124 dp[i][co][3] = dp[i-1][co][3] + (dis[i] - dis[i-1]) * 2; //与co的关系
    125 if(co > 1){
    126 if(dp[i][co][3] > dp[i-1][co-1][3] + dis[i] - dis[i-1] + 1) //与co-1的关系
    127 dp[i][co][3] = dp[i-1][co-1][3] + dis[i] - dis[i-1] + 1;
    128 if(dp[i][co][3] > dp[i-1][co-1][1] + dis[i] - dis[i-1] + 1)
    129 dp[i][co][3] = dp[i-1][co-1][1] + dis[i] - dis[i-1] + 1;
    130 if(dp[i][co][3] > dp[i-1][co-1][2] + dis[i] - dis[i-1] + 1)
    131 dp[i][co][3] = dp[i-1][co-1][2] + dis[i] - dis[i-1] + 1;
    132 }
    133 tmpLastMin = lastMin(i-1, co-2); //与co-2的关系
    134 if(dp[i][co][3] > tmpLastMin + 2)
    135 dp[i][co][3] = tmpLastMin + 2;
    136
    137 //4
    138 dp[i][co][4] = dp[i-1][co][4] + (dis[i] - dis[i-1]) * 2;
    139 tmpLastMin = lastMin(i-1, co-1);
    140 if(dp[i][co][4] > tmpLastMin + 2)
    141 dp[i][co][4] = tmpLastMin + 2;
    142 }
    143 }
    144
    145 //结果
    146 tmpLastMin = dp[newSize-1][k][3];
    147 if(tmpLastMin > dp[newSize-1][k][4])
    148 tmpLastMin = dp[newSize-1][k][4];
    149 if(sta[dis[newSize-1]] == 2 && tmpLastMin > dp[newSize-1][k][2]){
    150 tmpLastMin = dp[newSize-1][k][2];
    151 }
    152 else if(sta[dis[newSize-1]] == 1 && tmpLastMin > dp[newSize-1][k][1]){
    153 tmpLastMin = dp[newSize-1][k][1];
    154 }
    155
    156 printf("%d\n", tmpLastMin);
    157
    158
    159 return 0;
    160 }
  • 相关阅读:
    Centos 7 LVM xfs文件系统修复
    Feign报错'xx.FeignClientSpecification', defined in null, could not be registered.
    IDEA提示不区分大小写设置
    基于SpringBoot的多模块项目引入其他模块时@Autowired无法注入其他模块stereotype注解类对象的问题解决
    docker安装mysql
    [转]【收藏】用消息队列和消息应用状态表来消除分布式事务
    临时修改当前crontab编辑器
    golang处理 json中非法字符
    nsq里面WaitGroups两种实用的用法
    golang zlib 压缩,解压缩
  • 原文地址:https://www.cnblogs.com/longdouhzt/p/2377356.html
Copyright © 2011-2022 走看看