• CF#508 1038E Maximum Matching


    ~~~题面~~~

    题解:

      感觉还是比较妙的,复杂度看上去很高(其实也很高),但是因为n只有100,所以还是可以过的。

      考虑一个很暴力的状态f[i][j][x][y]表示考虑取区间i ~ j的方格,左右端点颜色分别是x, y.的最大值。

      那么有如下转移

      1,直接继承子区间的答案

        f[i][j][x][y] = max(f[i][k][x][y], f[k + 1][j][x][y]);//因为子区间就这2种,毕竟子区间一定比当前区间小,因此不靠在端点上的区间一定已经被靠在端点上的区间给取过max了。

      2,由2段子区间拼凑而来,相当于枚举中间断开的地方是选了那个块.//如果中间断开的地方的块没有被选,那么一定可以找到一个被选的块作为断点(如果找不到就说明这整个区间内只取了端点,再转移也没有什么意义。)

        翻转操作是不需要考虑的,因为可以在初始化的地方就处理掉,因此只需要在转移的地方考虑一下乱序继承即可。

        即正常的顺序是[i, l] + [l + 1, j] = [i, j];

        乱序则可以支持[l + 1][j] + [i, l] = [i, j];

        所以对于这2种情况都转移一下,转移的时候必须要求相接的地方颜色相同即可。

      注意因为有子区间相加转移的地方,所以初始化为极小值的时候不要太小了,不然太小了直接一加就爆了。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define R register int
     4 #define AC 110
     5 #define ac 6
     6 
     7 int n, ans;
     8 int f[AC][AC][ac][ac];
     9 
    10 inline int read()
    11 {
    12     int x = 0;char c = getchar();
    13     while(c > '9' || c < '0') c = getchar();
    14     while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    15     return x;
    16 }
    17 
    18 void pre()
    19 {
    20     n = read();
    21     memset(f, -63, sizeof(f));
    22     int a, b, c;
    23     for(R i = 1; i <= n; i ++)
    24     {
    25         a = read(), b = read(), c = read();
    26         f[i][i][a][c] = f[i][i][c][a] = b;
    27     }
    28 }
    29 
    30 inline void upmax(int &a, int b)
    31 {
    32     if(b > a) a = b;
    33 }
    34 
    35 void work()
    36 {
    37     for(R i = n; i; i --)
    38         for(R j = i; j <= n; j ++)
    39             for(R x = 1; x <= 4; x ++)
    40                 for(R y = 1; y <= 4; y ++)
    41                 {
    42                     for(R l = i; l < j; l ++)
    43                     {
    44                         upmax(f[i][j][x][y], max(f[i][l][x][y], f[l + 1][j][x][y]));
    45                         for(R k = 1; k <= 4; k ++)
    46                         {
    47                             upmax(f[i][j][x][y], f[i][l][x][k] + f[l + 1][j][k][y]);
    48                             upmax(f[i][j][x][y], f[i][l][k][y] + f[l + 1][j][x][k]);
    49                         }
    50                     }
    51                     upmax(ans, f[i][j][x][y]);
    52                 }
    53     printf("%d
    ", ans);
    54 }
    55 
    56 int main()
    57 {
    58     //freopen("in.in", "r", stdin);
    59     pre();
    60     work();
    61     //fclose(stdin);
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    linux下配置redis
    前端之JavaScript:JS之DOM对象一
    前端之JavaScript:JavaScript对象
    css样式之补充
    css属性中常见的操作方法
    css属性操作
    css选择器
    html 表单操作
    前端基础之html
    1231211221211221
  • 原文地址:https://www.cnblogs.com/ww3113306/p/9840159.html
Copyright © 2020-2023  润新知