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
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    微信公众平台开发教程(一) 微信公众账号注册流程
    DNS----域名解析系统
    C#编程总结(九)字符编码
    向大神学习
    C# 正则表达式
    js 正则表达式 取反
    H5 打开App
    Fiddler 过滤器的使用
    Fiddler 默认不能抓取页面信息的问题
    js 元素Dom新建并插入页面createElement
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/14421605.html
Copyright © 2011-2022 走看看