zoukankan      html  css  js  c++  java
  • 【Uva 1630】Folding

    Link:

    Description

    你能对字符串进行压缩的操作;
    即把连续出现的相同的子串改成它出现的次数+这个最基本的字符串的形式;
    问你这个字符串最短能被压缩得多短;

    Solution

    设f[i][j]表示,i..j这一段最短能压缩得多短;
    d[i][j]表示i..j这一段最短的形式压缩成的字符串是什么;
    对于一段i..j
    有两种可能
    1.是两个压缩串合并起来的;
    2.自己构成一个压缩串
    对于第一种,枚举间断点;
    对于第二种,看看最短的母串是什么,用最短的母串构造压缩;
    看看间断点自己构成重复的,哪一种更优;
    选择最优的就好;
    构造的时候,里面的东西也要是被压缩过的,因为压缩可以嵌套

    NumberOf WA

    0

    Reviw

    这是一种模型;
    即是由两个串并在一起,还是自己组成压缩串.
    题目中所给的定义很有用.

    Code

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 100;
    const int INF = 0x3f3f3f3f;
    
    string s,d[N+10][N+10];
    int f[N+10][N+10];
    int n;
    
    int ok(int l,int r){
        for (int i = 1;i <= r-l;i++)
        if ( (r-l+1)%i==0){
            bool ok = true;
            for (int j = l;j+i <= r;j++)
                if (s[j]!=s[j+i])
                    ok = false;
            if (ok) return i;
        }
        return 0;
    }
    
    int dfs(int l,int r)
    {
        if (f[l][r]!=-1) return f[l][r];
        if (l==r){
            f[l][r] = 1;
            d[l][r]="";d[l][r] += s[l];
            return f[l][r];
        }
        int mi = INF,pos;
        for (int i = l;i <= r-1;i++){
            int temp = dfs(l,i) + dfs(i+1,r);
            if (temp < mi){
                mi = temp;
                pos = i;
            }
        }
        d[l][r] = d[l][pos]+d[pos+1][r];
        int len = ok(l,r);
        if (len){
            int tlen = (r-l+1)/len;
            ostringstream ts;
            ts << tlen;
            string temp = ts.str();
            temp+="("+d[l][l+len-1]+")";
            if ((int)temp.size()<mi){
                d[l][r] = temp;
                mi = (int) temp.size();
            }
        }
        return f[l][r] = mi;
    }
    
    int main(){
        //freopen("F:\rush.txt","r",stdin);
        ios::sync_with_stdio(false);
        while (cin >> s){
            n = s.size();
            s = ' '+s;
            memset(f,-1,sizeof f);
            dfs(1,n);
            cout << d[1][n] <<endl;
        }
        return 0;
    }
  • 相关阅读:
    Visual Studio 2008 每日提示(四)
    修改XP注册到用户名和公司组织名
    Visual Studio技巧之打造拥有自己标识的代码模板
    收集的学习资料
    多个记录更新(存储过程)
    '1,2,3,68,10'转换为'1,2,3,6,7,8,10'
    .NET程序员面试的题一部 (转)
    [.net]DataGrid中绑定DropDownList[转]
    使用DELETE与TRUNCATE删除表所有行的区别
    sysobjects 各列的含义
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626172.html
Copyright © 2011-2022 走看看