KMP+区间dp csu1620 A Cure for the Common Code

传送门:点击打开链接

题意:可以把字符串用过括号折叠起来。现在给你原串,问折叠后最短是多少,len<=500

思路,首先,我们通过O(n^2)来预处理出每个区间里的最短循环节。

之后,我们直接按照区间dp用记忆化搜索去搞就行了。

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout << "[" << x << "]"
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w+", stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int MX = 1e3 + 5;
const int INF = 0x3f3f3f3f;

char S[MX];
int A[MX][MX], dp[MX][MX], Next[MX];

void GetNext(int n, char S[]) {
    Next[0] = 0;
    for(int i = 1; i < n; i++) {
        int j = Next[i - 1];
        while(j && S[i] != S[j]) j = Next[j - 1];
        Next[i] = S[i] == S[j] ? j + 1 : 0;
    }
}
int GetCir(int p) {
    return (p + 1) % (p - Next[p] + 1) ? p + 1 : p - Next[p] + 1;
}
int getlen(int n) {
    int ret = 0;
    while(n) {
        ret++; n /= 10;
    }
    return max(ret, 1);
}
void solve(int l, char S[], int dp[]) {
    int n = strlen(S);
    GetNext(n, S);
    for(int i = 0; i < n; i++) {
        A[l][l + i] = GetCir(i);
    }
}
int DP(int l, int r) {
    if(r - l + 1 == 1) return 1;
    if(r - l + 1 == 2) return 2;
    if(dp[l][r]) return dp[l][r];
    int cnt = (r - l + 1) / A[l][r], w = A[l][r], ans = r - l + 1;
    if(cnt != 1) ans = min(ans, DP(l, l + w - 1) + 2 + getlen(cnt));
    if(A[l][r] == 1) ans = min(ans, 1 + getlen(r - l + 1));
    for(int i = l; i <= r - 1; i++) {
        ans = min(ans, DP(l, i) + DP(i + 1, r));
    }
    return dp[l][r] = ans;
}

int main() {
    int ansk = 0; //FIN;
    while(~scanf("%s", S), S[0] != '0') {
        memset(dp, 0, sizeof(dp));

        int n = strlen(S);
        for(int i = 0; i < n; i++) {
            solve(i, S + i, A[i]);
        }
        printf("Case %d: %d\n", ++ansk, DP(0, n - 1));
    }
    return 0;
}


你可能感兴趣的:(KMP+区间dp csu1620 A Cure for the Common Code)