[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;
}