1. 程式人生 > 其它 >P4302 [SCOI2003]字串摺疊 提交 3.02k 通過 1.74k 時間限制 1.00s 記憶體限制 125.00MB

P4302 [SCOI2003]字串摺疊 提交 3.02k 通過 1.74k 時間限制 1.00s 記憶體限制 125.00MB

[SCOI2003]字串摺疊

題目描述

摺疊的定義如下: 1. 一個字串可以看成它自身的摺疊。記作S = S 2. X(S)是X(X>1)個S連線在一起的串的摺疊。記作X(S) = SSSS…S(X個S)。 3. 如果A = A’, B = B’,則AB = A’B’ 例如,因為3(A) = AAA, 2(B) = BB,所以3(A)C2(B) = AAACBB,而2(3(A)C)2(B) = AAACAAACBB 給一個字串,求它的最短折疊。例如AAAAAAAAAABABABCCD的最短折疊為:9(A)3(AB)CCD。

輸入輸出格式

輸入格式

僅一行,即字串S,長度保證不超過100。

輸出格式

僅一行,即最短的摺疊長度。

輸入輸出樣例

輸入樣例 #1

NEERCYESYESYESNEERCYESYESYES

輸出樣例 #1

14

說明

一個最短的摺疊為:2(NEERC3(YES))
#include <cstdio>
#include <algorithm>
#include <cstring>

using namespace std;
const int N = 200;
char s[N];
int f[N][N];
int n;


bool check(int l,int r,int len)
{
    for(int i = l ;i <= r; i++)
    {
        
for(int j = i + len ; j <= r; j += len) { if(s[i] != s[j]) return 0; } } return 1; } int calc(int x) { if(x <= 9) return 1; else if (x >= 10 && x<=99) { return 2; } return 3; } int main() { scanf("%s",s + 1); n
= strlen(s + 1); for(int len = 1; len <= n; len ++) { for(int l = 1; l + len - 1 <= n; l++ ) { int r = l + len - 1; f[l][r] = len; for(int k = l; k < r; k++) { f[l][r] = min(f[l][r], f[l][k] + f[k + 1][r]); } for(int k = 1; k <= len; k++) { if(len % k) continue; if(check(l ,r, k)) { f[l][r] = min(f[l][r] , f[l][l + k - 1] + calc(len/k) + 2); } } } } printf("%d", f[1][n]); return 0; }