zoukankan      html  css  js  c++  java
  • NC20252 压缩(区间dp)

    一道区间dp题

    我们发现由于有了M的限制,所以合并区间的时候并不能直接合并,因为不是从区间左端点开始的

    因此考虑三维状态设计

    f[i][j][0/1]表示i-j中是否存在M

    对于不存在的情况,他有两种更新方式,一种是直接合并,一种是当偶数时,可以折半合并

    对于存在的情况,这个M相当于把一个大区间的合并变成了两个小区间,因为M之后的这一段的开头相当于M之后的第一个字母。因此我们枚举M的位置进行更新

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    const int inf=0x3f3f3f3f;
    int f[110][100][2];
    string s;
    bool check(int l,int r){
        int mid=(l+r)>>1;
        for(int i=l;i<=mid;++i){
            if(s[i]!=s[mid+i-l+1])
                return false;
        }
        return true;
    }
    int main(){
        ios::sync_with_stdio(false);
        int i,j,k;
        cin>>s;
        int n=s.size();
        s=" "+s;
        for(int len=1;len<=n;len++){
            for(i=1;i+len-1<=n;i++){
                j=i+len-1;
                f[i][j][0]=len;
                f[i][j][1]=inf;
                for(k=i;k<=j;k++){
                    f[i][j][0]=min(f[i][j][0],f[i][k][0]+j-k);
                    f[i][j][1]=min(f[i][j][1],min(f[i][k][1],f[i][k][0])+min(f[k+1][j][1],f[k+1][j][0])+1);
                }
                if(len%2==0&&check(i,j)){
                    f[i][j][0]=min(f[i][j][0],f[i][(i+j)/2][0]+1);
                }
            }
        }
        cout<<min(f[1][n][0],f[1][n][1])<<endl;
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    javaweb:Filter过滤器
    javaScript:高级
    javascript:基础
    Boostrao:轮播图
    Bootstrap案列:首页界面
    Bootstrap学习笔记
    javaweb:respone
    javaweb:jsp
    五、结构型模式--->07.享元模式
    五、结构型模式--->06.组合模式
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14421605.html
Copyright © 2011-2022 走看看