【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;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626172.html