zoukankan      html  css  js  c++  java
  • bzoj1068: [SCOI2007]压缩

    区间dp。

    bool t代表区间内是否能含M。

    如果不能含M的话有 res=min{f[l][i][0]+r-i}。(i<r) (串长的最小值等于前面串压缩后的最小值和不压缩后面串的长度)。

    如果字符串长度为偶数,且前半串等于后半串,还有 f[l][r][t]=min(f[l][(l+r)>>1][t]+1) (后半串用1个R替代)。

    如果t=1时,除上面俩个还有res=min{f[l][i][1]+1+f[i+1][r][1]}。

    状态和3种状态转移方程比较难想。很大程度是因为对区间dp不熟悉。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 50 + 10;
    int f[maxn][maxn][2];
    char s[100];
    
    bool same(int l,int r) {
        int n=r-l+1;
        if(n%2) return 0;
        int mid=(l+r)>>1;
        for(int i=l,j=mid+1;i<=mid;i++,j++) if(s[i]!=s[j]) return 0;
        return 1;
    }
    
    int dp(int l,int r,bool t) {
        if(l==r) return 1;
        if(f[l][r][t]) return f[l][r][t];
        int &res=f[l][r][t];
        res=r-l+1;
        if(t) for(int i=l;i<r;i++) res=min(res,dp(l,i,1)+dp(i+1,r,1)+1);
        for(int i=l;i<r;i++) res=min(res,dp(l,i,t)+r-i);
        if(same(l,r)) res=min(res,dp(l,(l+r)>>1,0)+1);    
        return res;
    }
    
    int main() {
        scanf("%s",s+1);
        printf("%d
    ",dp(1,strlen(s+1),1));
        return 0;
    }
  • 相关阅读:
    HDU 2896 病毒侵袭 (AC自动机)
    HDU 2222 Keywords Search (AC自动机)
    HDU 2457 DNA repair (AC自动机+DP)
    CoFun 1612 单词分组(容斥)
    邓_mysql_面试
    Html5+js测试题(开发版)
    Html5+js测试题【完整版】
    HTML面试
    支付宝+微信=合成二维码
    邓_laravel框架——news
  • 原文地址:https://www.cnblogs.com/invoid/p/5662140.html
Copyright © 2011-2022 走看看