zoukankan      html  css  js  c++  java
  • Luogu 2470 [SCOI2007]压缩

    和Luogu 4302 [SCOI2003]字符串折叠 差不多的想法,区间dp

    为了计算方便,我们可以假设区间[l, r]的前面放了一个M,设$f_{i, j, 0/1}$表示区间$[i, j]$中是否存在M

    因为这题只能是二的幂次倍压缩,所以转移的时候枚举中点chk是否合法,如果合法那么

      $f_{i, j, 0} = f_{i, (i + j) / 2 - 1, 0} + 1$

    除了区间压缩,还可以通过加法构成最优答案

    1、当中间加入了M,枚举M加入的位置 $f_{i, j, 1} = min(min(f_{i, k, 1}, f_{i, k, 0}) + min(f_{k + 1, r, 0}, f_{k + 1, r, 1}) + 1)$  $(i - 1 <k < j)$

    2、当中间没有M的时候,相当于后面的子串不存在压缩

        $f_{i, j, 1} = min(f_{i, k, 0} + j - k)$ $(i - 1 < k < j)$

    时间复杂度为不严格的$O(n^{3})$(只是一个上界?)

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    const int N = 55;
    
    int n, f[N][N][2];
    char s[N];
    
    inline int min(int x, int y) {
        return x > y ? y : x;
    }
    
    inline void chkMin(int &x, int y) {
        if(y < x) x = y;
    }
    
    inline bool chk(int l, int r) {
        int len = (r - l + 1) / 2;
        for(int i = l; i <= r - len; i++)
            if(s[i] != s[i + len]) return 0;
        return 1;
    }
    
    int main() {
    //    freopen("3.in", "r", stdin);
        
        scanf("%s", s + 1);
        n = strlen(s + 1);
        
        memset(f, 0x3f, sizeof(f));
        for(int len = 1; len <= n; len++) {
            for(int l = 1; l + len - 1 <= n; l++) {
                int r = l + len - 1;
                chkMin(f[l][r][0], len), chkMin(f[l][r][1], len);
                
                if(len % 2 == 0 && chk(l, r)) 
                    chkMin(f[l][r][0], 1 + f[l][l + len / 2 - 1][0]);
                
                for(int k = l; k < r; k++) {
                    chkMin(f[l][r][1], min(f[l][k][0], f[l][k][1]) + 1 + min(f[k + 1][r][1], f[k + 1][r][0]));
                    chkMin(f[l][r][0], f[l][k][0] + r - k);
                }
            }
        }
        
        printf("%d
    ", min(f[1][n][0], f[1][n][1]));
        return 0;
    }
    View Code
  • 相关阅读:
    461. Hamming Distance
    342. Power of Four
    326. Power of Three
    368. Largest Divisible Subset java solutions
    95. Unique Binary Search Trees II java solutions
    303. Range Sum Query
    160. Intersection of Two Linked Lists java solutions
    88. Merge Sorted Array java solutions
    67. Add Binary java solutions
    14. Longest Common Prefix java solutions
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9484311.html
Copyright © 2011-2022 走看看