您的位置:首页 > 其它

bzoj1068 [SCOI2007]压缩

2018-02-20 11:26 197 查看

1068: [SCOI2007]压缩

Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 1574 Solved: 1004
[Submit][Status][Discuss]

Description

  给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息。压缩后的字符串除了小
写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前位置左边没
有M,则从串的开始算起)开始的解压结果(称为缓冲串)。 bcdcdcdcd可以压缩为bMcdRR,下面是解压缩的过程



  另一个例子是abcabcdabcabcdxyxyz可以被压缩为abcRdRMxyRz。

Input

  输入仅一行,包含待压缩字符串,仅包含小写字母,长度为n。

Output

  输出仅一行,即压缩后字符串的最短长度。

Sample Input

bcdcdcdcdxcdcdcdcd

Sample Output

12

HINT

在第一个例子中,解为aaaRa,在第二个例子中,解为bMcdRRxMcdRR。

【限制】

100%的数据满足:1<=n<=50 100%的数据满足:1<=n<=50

分析:挺巧妙的一道题.

   首先可以一眼看出来这是一个区间dp,但是直接想状态以及状态转移方程很难.一般的区间dp状态都表示为f[l][r]表示将区间[l,r]处理后的最小长度,但在这题里似乎还缺点什么.

   考虑一下搜索.首先需要知道,在串的左侧默认有一个“M”,这是不计入串长的.每次搜区间[l,r]能被压缩成多短.接下来你有几种操作:1.找个位置放R. 2.找个位置放M.

   对于第一个操作,如果R放在串的中间正好,那么这个串的长度就缩成了一半,可以递归处理下去. 如果R放在偏右位置,没有意义.如果R放在偏左位置,那么可以将串一分为二,左边放了R的部分继续递归,右边就用原串,结束递归. question:为什么在这里不讨论右边放R呢?如果右边放R,那么前面必有一个M,这就属于第二个操作了.

   对于第二个操作,找了一个位置放M后,可以发现左右两半就是一模一样的子问题了,递归下去.

   可以发现,第二个操作的M对于第一个操作的R是一个制约左右,只有左边放了M才能放R.

   到这里,记忆化搜索一下就可以了.当然,也可以用递推.令f[i][j][0/1]表示区间[l,r]中有没有放M压缩后最短的串. 具体的递推方程看我的代码吧:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int inf = 0x7ffffff;

char s[60];
int len,f[60][60][2];

bool check(int x,int y)
{
if ((y - x + 1) & 1)
return false;
int mid = (x + y) >> 1;
for (int i = 1; i <= mid - x + 1; i++)
{
if (s[i + x - 1] != s[mid + i])
return false;
}
return true;
}

int main()
{
scanf("%s",s + 1);
len = strlen(s + 1);
for (int l = 1; l <= len; l++)
{
for (int i = 1; i + l - 1 <= len; i++)
{
int j = i + l - 1;
f[i][j][0] = f[i][j][1] = (j - i + 1);
for (int k = i; k < j; k++)
f[i][j][1] = min(f[i][j][1],min(f[i][k][0],f[i][k][1]) + 1 + min(f[k + 1][j][0],f[k + 1][j][1]));
for (int k = i; k < j; k++)
f[i][j][0] = min(f[i][j][0],f[i][k][0] + j - k);
if (check(i,j))
f[i][j][0] = min(f[i][j][0],f[i][(i + j) >> 1][0] + 1);
}
}
printf("%d\n",min(f[1][len][0],f[1][len][1]));

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: