[bzoj] 1090 字符串折叠 || 区间dp

原题


f[i][j]表示i到j压缩的长度
f[i][j]=max(f[i][j],f[i][k]+f[k][j])
if (check(i,k,j))(即k+1到j可以由i到k重复得到) f[i][j]=max(f[i][j],f[i][k]+2+calc((d+1)/(k-i+1)))
//calc用于计算一个数字占字符长度

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 110
using namespace std;
char s[N];
int l,f[N][N];

int calc(int x)
{
    int ans=0;
    while (x) ans++,x/=10;
    return ans;
}

bool check(int l,int k,int r)
{
    if ((r-k)%(k-l+1)!=0) return 0;
    for (int i=k+1,j=l;i<=r;i++,j++)
    {
	if (j>k) j=l;
	if (s[i]!=s[j]) return 0;
    }
    return 1;
}

int main()
{
    scanf("%s",s+1);
    l=strlen(s+1);
    for (int i=1;i<=l;i++) f[i][i]=1;
    for (int d=1;d<=l;d++)
	for (int i=1;i+d<=l;i++)
	{
	    int j=i+d;
	    f[i][j]=d+1;
	    for (int k=i;k<j;k++)
	    {
		f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);
		if (check(i,k,j))
		    f[i][j]=min(f[i][j],f[i][k]+2+calc((d+1)/(k-i+1)));
	    }
	}
    printf("%d\n",f[1][l]);
    return 0;
}
posted @ 2018-01-09 09:43  Mrha  阅读(132)  评论(0编辑  收藏  举报