bzoj1090:[SCOI2003]字符串折叠

思路:区间dp,令f[l][r]表示l到r的答案,于是f[l][r]=min(f[l][mid],f[mid+1][r]),如果能折叠f[l][r]=min(f[l][r],f[l][l+len-1]+calc(r-l+1,len),calc是计算数字的长度。记忆化搜索即可。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7
 8 char s[105];
 9 int f[105][105];
10
11 bool check(int l,int r,int len){
12     for (int i=l;;i+=len){
13         if (i+len>r) break;
14         for (int j=i;j<=i+len-1;j++)
15             if (s[j]!=s[j+len] && j+len<=r) return 0;
16     }
17     return 1;
18 }
19
20 int calc(int n,int len){
21     int ans=0;n/=len;while (n) n/=10,ans++;return ans;
22 }
23
24 int dp(int l,int r){
25     if (l==r) return f[l][r]=1;
26     if (f[l][r]) return f[l][r];
27     int len=r-l+1;f[l][r]=r-l+1;
28     for (int mid=l;mid<r;mid++) f[l][r]=min(f[l][r],dp(l,mid)+dp(mid+1,r));
29     for (int L=1;L<len;L++) if (len%L==0 && check(l,r,L)) f[l][r]=min(f[l][r],dp(l,l+L-1)+2+calc(len,L));
30     return f[l][r];
31 }
32
33 int main(){
34     scanf("%s",s+1);
35     printf("%d",dp(1,strlen(s+1)));
36     return 0;
37 }

时间: 2024-12-16 02:35:25

bzoj1090:[SCOI2003]字符串折叠的相关文章

BZOJ1090: [SCOI2003]字符串折叠

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1090 Description 折叠的定义如下: 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)?AAACAA

BZOJ 1090: [SCOI2003]字符串折叠( 区间dp )

按照题意dp...dp(l, r) = min{ dp(l, x) + dp(x+1, r) , 折叠(l, r) } 折叠(l, r)我是直接枚举长度然后哈希判.. -------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int maxn = 109; con

【BZOJ-1090】字符串折叠 区间DP + Hash

1090: [SCOI2003]字符串折叠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1127  Solved: 737[Submit][Status][Discuss] Description 折叠的定义如下: 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) =

[SCOI2003]字符串折叠(区间dp)

P4302 [SCOI2003]字符串折叠 题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS-S(X个S). 如果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的最短折叠为

bzoj 1090 [SCOI2003]字符串折叠(区间DP)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1090 [题意] 给定一个字符串,问将字符串折叠后的最小长度. [思路] 设f[i][j]表示将区间ij折叠后的最小长度,则有转移式: f[i][j]=min{ j-i+1,f[i][k]+f[k+1][j],f[i][i+x-1]+2+digit((j-i+1)/x) } 第一项代表不折叠,第二项代表当前不折叠,第三项代表以x长度折叠ij区间,条件是满足ij区间以x为循环节. [代码

【BZOJ 1090】[SCOI2003]字符串折叠

Description 折 叠的定义如下: 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

【BZOJ】1090: [SCOI2003]字符串折叠(dp)

http://www.lydsy.com/JudgeOnline/problem.php?id=1090 随便yy一下.. 设f[i,j]表示i-j的最小长度 f[i, j]=min{j-i+1, f[i,k]+f[k+1, j], count[x]+2+f[i, i+x-1]},其中count[x]表示x的位数,最后边的转移那个条件是i~j都是长度为x的串连在一起. 然后最后那个转移暴力233可以水过... #include <cstdio> #include <cstring>

P4302 [SCOI2003]字符串折叠

题目描述 折叠的定义如下: 一个字符串可以看成它自身的折叠.记作S = S X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S) = SSSS…S(X个S). 如果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. 输入输出格式

BZOJ 1090 SCOI2003 字符串折叠 动态规划+Hash

题目大意:给定一个字符串,求按照题中所给的压缩方式最短能压缩到多长 区间DP 令f[i][j]表示[i,j]区间内的字符串最短能压缩到多长 普通的区间DP:f[i][j]=min{f[i][k]+f[k+1][j]} (i<=k<=j-1) 此外如果对这段字符串进行压缩,那么我们可以枚举循环节,用Hash来判断 如果k是一个循环节,那么有f[i][j]=min(f[i][j],f[i][i+k-1]+digit[len/k]+2) 其中len=j-i+1,digit表示一个数在十进制下的长度