【bzoj1090】[SCOI2003]字符串折叠
2017-11-09 09:11
477 查看
1090: [SCOI2003]字符串折叠
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1652 Solved: 1093
[Submit][Status][Discuss]
Description
折叠的定义如下: 1. 一个字符串可以看成它自身的折叠。记作S S 2. X(S)是X(X>1)个S连接在一起的串的折叠。记作X(S) SSSS…S(X个S)。 3. 如果A A’, BB’,则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。
Input
仅一行,即字符串S,长度保证不超过100。Output
仅一行,即最短的折叠长度。Sample Input
NEERCYESYESYESNEERCYESYESYESSample Output
14HINT
一个最短的折叠为:2(NEERC3(YES))Source
[Submit][Status][Discuss]
区间DP
设f[i][j]为区间[i,j]的答案
显然有f[i][j] = min{f[i][k] + f[k + 1][j]} (i <= k < j)
如果[i,k]能够折叠[k + 1,j]的时候,还有f[i][j] = min{f[i][k] + 2 + bit((j - i + 1) / (k - i + 1))}
其中bit(x)为计算x的十进制位数的函数
代码:
#include<cstdio> #include<cmath> #include<queue> #include<stack> #include<vector> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; const int INF = 2147483647; const int maxn = 110; char s[maxn]; int n,f[maxn][maxn],maxlen[maxn][maxn]; inline LL getint() { LL ret = 0,f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') ret = ret * 10 + c - '0',c = getchar(); return ret * f; } inline int cal(int x) { int cnt = 0; while (x) cnt++ , x /= 10; return cnt; } int main() { scanf("%s",s + 1); n = strlen(s + 1); for (int i = 1; i <= n; i++) for (int j = i; j <= n; j++) for (int k = 1; k <= n; k++) { bool tmp = 0; if (i + k * (j - i + 1) > n) break; for (int l = 0; l <= j - i; l++) if (s[i + l] != s[i + k * (j - i + 1) + l]) { tmp = 1; break; } if (tmp) break; maxlen[i][j] = k; } for (int i = 1; i <= n; i++) f[i][i] = 1; for (int len = 1; len <= n; len++) for (int i = 1; i <= n; i++) { int j = i + len; int test; if (i == 6 && j == 14) test = 1; f[i][j] = INF; for (int k = i; k < j; k++) f[i][j] = min(f[i][j],f[i][k] + f[k + 1][j]); for (int k = i; k < j; k++) { if ((j - i + 1) % (k - i + 1) != 0) continue; if (maxlen[i][k] + 1 >= (j - i + 1) / (k - i + 1)) f[i][j] = min(f[i][j],f[i][k] + 2 + cal((j - i + 1) / (k - i + 1))); } } printf("%d",f[1] ); return 0; }
相关文章推荐
- bzoj 1090 [SCOI2003]字符串折叠
- [BZOJ 1090][SCOI 2003]字符串折叠(DP)
- BZOJ 1090[SCOI2003]字符串折叠 | 区间DP
- [bzoj1090][SCOI2003]字符串折叠_区间dp
- BZOJ 1090: [SCOI2003]字符串折叠|动态规划
- 【BZOJ1090】【SCOI2003】字符串折叠 {区间dp}
- bzoj1090: [SCOI2003]字符串折叠 区间dp+hash
- BZOJ 1090 [SCOI2003]字符串折叠 区间DP
- [DP] BZOJ1090: [SCOI2003]字符串折叠
- bzoj1090 [SCOI2003]字符串折叠
- bzoj1090 [SCOI2003]字符串折叠
- 【BZOJ1090 || SCOI2003】字符串折叠
- BZOJ1090: [SCOI2003]字符串折叠 区间DP
- 【BZOJ 1090】【SCOI 2003】字符串折叠 【区间DP】
- BZOJ 1090: [SCOI2003]字符串折叠 区间DP
- 【BZOJ 1090】 [SCOI2003]字符串折叠
- bzoj1090: [SCOI2003]字符串折叠
- BZOJ 1090 SCOI 2003 字符串折叠 区间DP
- BZOJ 1090: [SCOI2003]字符串折叠 区间动归
- BZOJ1090 [SCOI2003]字符串折叠