zoukankan      html  css  js  c++  java
  • [BZOJ] 1032 [JSOI2007]祖码

    似乎这道题是一道假题,因为std没考虑完全,导致有很多hack数据可以hack。。

    各种题解也都被各种hack,似乎只能暴搜写??

    难怪我30min就切掉了,算了假算法就假算法吧,来讲讲我的假做法。

    BZOJ上有另一道Zuma2,那道题的做法是真的,那道题在我之前的博文里面有,这里不提了。

    错误做法就是区间dp((

    设$g[i][j]$表示消除$[i,j]$的最小代价。  

    有两种方式可以消除:  

    1.分成两段,左右两边分别消除。

    2.消除中间的一堆,然后剩下左右两边的合并再消除。

    其实还有一种就是可以把跟两边相同的全部合并消除,不过那样子就有很多很多情况要讨论了,因为三个东西碰到一起就会自动消除,所以在掏空中间的时候会遇到很多问题,而std估计没考虑这种情况,所以这是个假题。

    所以状态转移方程就很好写了。

    $g[i][j] = min{g[i][k - 1] + g[k][j], g[l][r] + cost_{combine}}$。  

    每次判断两边多少个同色然后合并就好了。。

     1 #include <bits/stdc++.h>
     2 #define Mid ((l + r) / 2)
     3 #define lson (rt << 1)
     4 #define rson (rt << 1 | 1)
     5 using namespace std;
     6 int read() {
     7     char c; int num, f = 1;
     8     while(c = getchar(),!isdigit(c)) if(c == '-') f = -1; num = c - '0';
     9     while(c = getchar(), isdigit(c)) num = num * 10 + c - '0';
    10     return f * num;
    11 }
    12 const int N = 509;
    13 int n, a[N], g[N][N];
    14 signed main()
    15 {
    16     memset(g, 0x3f, sizeof(g));
    17     n = read();
    18     for(int i = 1; i <= n; i++) a[i] = read();
    19     for(int i = 1; i <= n; i++) g[i][i] = 2;
    20     for(int len = 2; len <= n; len++) {
    21         for(int i = 1; i + len - 1 <= n; i++) {
    22             int j = i + len - 1;
    23             for(int k = i + 1; k <= j; k++) 
    24                 g[i][j] = min(g[i][j], g[i][k - 1] + g[k][j]);
    25             int l = i, r = j;
    26             if(a[l] != a[r]) continue;
    27             while(l < j && a[l + 1] == a[l]) l++;
    28             while(r > i && a[r - 1] == a[r]) r--;
    29             if(l == j) g[i][j] = min(g[i][j], (j - i + 1) >= 2 ? 1 : (3 - (j - i + 1)));
    30             else {
    31                 if((l - i + 1) + (j - r + 1) >= 3) g[i][j] = min(g[i][j], g[l + 1][r - 1]);
    32                 else g[i][j] = min(g[i][j], g[l + 1][r - 1] + 3 - ((l - i + 1) + (j - r + 1)));
    33             }
    34         }
    35     }
    36     printf("%d
    ", g[1][n] == 3 ? 2 : g[1][n]);
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    CentOS
    Ubuntu
    Ubuntu
    Ubuntu
    2020-10-12 分享——Bigdata & ML Development WITH SCALA/python & SPARK (待续)
    postgresql 自增列 初始值设置
    白话布隆过滤器BloomFilter(转发)
    Typora ---一款简洁的Markdown编辑器
    postman —— API测试工具 && HTTP请求 (filddler 同类)
    K8S —— 学习资料(待看)
  • 原文地址:https://www.cnblogs.com/onglublog/p/14711198.html
Copyright © 2011-2022 走看看