zoukankan      html  css  js  c++  java
  • LOJ#2668 书法家

    题意:要在一张网格纸上画出NOI图形,使得所占格子的权值和最大。

    解:暴力DP即可...

    从左往右,每个字母都可以被划分成三块,且每块都可用上下两维来表示。

    于是一块一块的DP。考虑如何O(1)转移。显然只有N的中间那一块不好转移,别的都是直接转移。

    N的三块的两个连接处之间,可以枚举必须持平的那个端点,另一个用前缀最值。

    N第二块内部,考虑枚举后一个矩形的上边界,逐步扩展下边界。此时发现每扩展一步,可能的决策集合会增加:左边一格,下边界为刚扩展的那一格,上边界在枚举的上边界以上的所有状态。

    于是对于每个下边界,预处理出上边界从上到下的一个前缀最值,加到决策集合里取max即可。

      1 #include <bits/stdc++.h>
      2 
      3 const int INF = 0x3f3f3f3f;
      4 
      5 #define g f[FLAG]
      6 #define h f[FLAG ^ 1]
      7 
      8 int f[2][510][155][155], FLAG, n, m;
      9 int s[155][510], p[510], temp[155][155];
     10 
     11 inline int getSum(int i, int l, int r) {
     12     if(l > r) return 0;
     13     return s[r][i] - s[l - 1][i];
     14 }
     15 
     16 inline void out() {
     17     for(int i = 1; i <= m; i++) {
     18         for(int up = 1; up <= n; up++) {
     19             for(int down = up; down <= n; down++) {
     20                 printf("%d ", g[i][up][down]);
     21             }
     22         }
     23         puts("");
     24     }
     25     puts("");
     26     return;
     27 }
     28 
     29 inline void outp() {
     30     printf("p : ");
     31     for(int i = 1; i <= m; i++) {
     32         printf("%d ", p[i]);
     33     }
     34     puts("");
     35     puts("");
     36     return;
     37 }
     38 
     39 int main() {
     40     //printf("%d 
    ", sizeof(f) / 1048576);
     41 
     42     scanf("%d%d", &n, &m);
     43     for(int i = 1; i <= n; i++) {
     44         for(int j = 1; j <= m; j++) {
     45             scanf("%d", &s[i][j]);
     46             s[i][j] += s[i - 1][j];
     47         }
     48     }
     49 
     50     FLAG = 1; /// N 1
     51     memset(g, ~0x3f, sizeof(g));
     52     for(int i = 1; i <= m; i++) {
     53         for(int up = 1; up < n; up++) {
     54             for(int down = up + 1; down <= n; down++) {
     55                 g[i][up][down] = std::max(0, g[i - 1][up][down]) + getSum(i, up, down);
     56             }
     57         }
     58     }
     59 
     60     //out();
     61 
     62     FLAG ^= 1; /// N 1.5
     63     memset(g, ~0x3f, sizeof(g));
     64     for(int i = 1; i <= m; i++) {
     65         for(int up = 1; up < n; up++) {
     66             int large = -INF;
     67             for(int down = n - 1; down >= up; down--) {
     68                 large = std::max(large, h[i - 1][up][down + 1]);
     69                 g[i][up][down] = large + getSum(i, up, down);
     70             }
     71         }
     72     }
     73 
     74     //out();
     75 
     76     FLAG ^= 1; /// N 2
     77     //memset(g, ~0x3f, sizeof(g));
     78     memcpy(g, h, sizeof(h));
     79     for(int i = 1; i <= m; i++) {
     80         memset(temp, ~0x3f, sizeof(temp));
     81         for(int down = 1; down <= n; down++) {
     82             for(int up = 1; up <= down; up++) {
     83                 temp[down][up] = std::max(temp[down][up - 1], std::max(g[i - 1][up][down], h[i - 1][up][down]));
     84             }
     85         }
     86         for(int up = 1; up <= n; up++) {
     87             int large = temp[up - 1][up - 1];
     88             for(int down = up; down <= n; down++) {
     89                 large = std::max(large, temp[down][up]);
     90                 g[i][up][down] = std::max(large + getSum(i, up, down), h[i][up][down]);
     91             }
     92         }
     93     }
     94 
     95     //out();
     96 
     97     FLAG ^= 1; /// N 2.5
     98     memset(g, ~0x3f, sizeof(g));
     99     for(int i = 1; i <= m; i++) {
    100         for(int down = 2; down <= n; down++) {
    101             int large = -INF;
    102             for(int up = down - 1; up >= 1; up--) {
    103                 large = std::max(large, h[i - 1][up + 1][down]);
    104                 g[i][up][down] = large + getSum(i, up, down);
    105             }
    106         }
    107     }
    108 
    109     //out();
    110 
    111     FLAG ^= 1; /// N 3
    112     memset(g, ~0x3f, sizeof(g));
    113     for(int i = 1; i <= m; i++) {
    114         for(int up = 1; up < n; up++) {
    115             for(int down = up + 1; down <= n; down++) {
    116                 g[i][up][down] = std::max(h[i][up][down], g[i - 1][up][down] + getSum(i, up, down));
    117             }
    118         }
    119     }
    120 
    121     //out();
    122 
    123     /// get p : max of g
    124     memset(p, ~0x3f, sizeof(p));
    125     for(int i = 1; i <= m; i++) {
    126         p[i] = p[i - 1];
    127         for(int up = 1; up <= n; up++) {
    128             for(int down = 1; down <= n; down++) {
    129                 p[i] = std::max(p[i], g[i][up][down]);
    130             }
    131         }
    132     }
    133 
    134     //outp();
    135 
    136     //out();
    137 
    138     //printf(" O 1 
    ");
    139 
    140     FLAG ^= 1; /// O 1
    141     memset(g, ~0x3f, sizeof(g));
    142     for(int i = 5; i <= m; i++) {
    143         for(int up = 1; up < n - 1; up++) {
    144             for(int down = up + 2; down <= n; down++) {
    145                 g[i][up][down] = p[i - 2] + getSum(i, up, down);
    146             }
    147         }
    148     }
    149 
    150     //out();
    151 
    152     //printf(" O 2 
    ");
    153 
    154     FLAG ^= 1; /// O 2
    155     memset(g, ~0x3f, sizeof(g));
    156     for(int i = 1; i <= m; i++) {
    157         for(int up = 1; up < n - 1; up++) {
    158             for(int down = up + 2; down <= n; down++) {
    159                 g[i][up][down] = std::max(h[i - 1][up][down], g[i - 1][up][down]) + getSum(i, up, up) + getSum(i, down, down);
    160             }
    161         }
    162     }
    163 
    164     //out();
    165 
    166     FLAG ^= 1; /// O 3
    167     memset(g, ~0x3f, sizeof(g));
    168     for(int i = 1; i <= m; i++) {
    169         for(int up = 1; up < n - 1; up++) {
    170             for(int down = up + 2; down <= n; down++) {
    171                 g[i][up][down] = h[i - 1][up][down] + getSum(i, up, down);
    172             }
    173         }
    174     }
    175 
    176     //out();
    177 
    178     /// get p : max of g
    179     memset(p, ~0x3f, sizeof(p));
    180     for(int i = 1; i <= m; i++) {
    181         p[i] = p[i - 1];
    182         for(int up = 1; up < n - 1; up++) {
    183             for(int down = up + 2; down <= n; down++) {
    184                 p[i] = std::max(p[i], g[i][up][down]);
    185             }
    186         }
    187     }
    188 
    189     //outp();
    190 
    191     //out();
    192 
    193     FLAG ^= 1; /// I 1
    194     memset(g, ~0x3f, sizeof(g));
    195     for(int i = 5; i <= m; i++) {
    196         for(int up = 1; up < n - 1; up++) {
    197             for(int down = up + 2; down <= n; down++) {
    198                 g[i][up][down] = std::max(p[i - 2], g[i - 1][up][down]) + getSum(i, up, up) + getSum(i, down, down);
    199             }
    200         }
    201     }
    202 
    203     //out();
    204 
    205     FLAG ^= 1; /// I 2
    206     memset(g, ~0x3f, sizeof(g));
    207     for(int i = 1; i <= m; i++) {
    208         for(int up = 1; up < n - 1; up++) {
    209             for(int down = up + 2; down <= n; down++) {
    210                 g[i][up][down] = std::max(g[i - 1][up][down], h[i - 1][up][down]) + getSum(i, up, down);
    211             }
    212         }
    213     }
    214 
    215     //out();
    216     int ans = -INF;
    217 
    218     FLAG ^= 1; /// I 3
    219     memset(g, ~0x3f, sizeof(g));
    220     for(int i = 1; i <= m; i++) {
    221         for(int up = 1; up < n - 1; up++) {
    222             for(int down = up + 2; down <= n; down++) {
    223                 g[i][up][down] = std::max(g[i - 1][up][down], h[i - 1][up][down]) + getSum(i, up, up) + getSum(i, down, down);
    224                 ans = std::max(g[i][up][down], ans);
    225             }
    226         }
    227     }
    228 
    229     //out();
    230 
    231     printf("%d
    ", ans);
    232     return 0;
    233 }
    AC代码
  • 相关阅读:
    Redis 思维导图 (解析版)
    一张图片了解redis
    Redis 思维导图
    计算机网络协议
    IT笔面试题
    Hadoop集群搭建
    天涯论坛只看楼主
    齐秦&r大约在冬季现场版
    郁可唯茶汤现场版
    MTK平台电路设计01
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10778347.html
Copyright © 2011-2022 走看看