uva3363
题意是:压缩字符串,,abababa可以压缩为a3(ab),,要是压缩后的字符串尽量短,,
此题是一个简易的区间DP还是很简单的,,,做完这个题目,,感觉自己的能力上升了不少,,对于区间Dp有了新的理解,,
Dp[l][r]=min(dp[i][r]+dp[i+1][r],自身压缩后的长度);
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
char s[205];
int n;
int dp[205][205];
int judge(int l,int r)
{
int flag,j;
int tag=0;
for(int i=1;i<=(r-l+1)/2;i++)
{
tag=i;
flag=0;
if((r-l+1)%i==0)
{
for(int j=l;j<=r-i+1;j=j+i)
{
if(flag==1)
break;
for(int k=0;k<i;k++)
{
if(s[l+k]!=s[j+k])
{
flag=1;
break;
}
}
}
}
else
{
flag=1;
}
if(flag==0){
// printf("tag=====%d\n",tag);
break;
}
}
// printf("%d %d %d\n",l,r,tag);
if(flag==0)
return tag;
else
return 0;
}
int check(int l,int r,int pos)
{
int cnt=-1;
int qu=(pos-l+1);
for(int i=pos;i<=r;i+=qu)
{
cnt++;
for(int j=1;j<=pos-l+1;j++)
{
if(s[i+j]!=s[l+j-1])
{
return cnt;
}
}
}
return cnt;
}
int getsum(int k)
{
int a=0;
while(k!=0)
{
k=(k-k%10)/10;
a++;
}
return a;
}
int Dp(int l,int r)
{
//printf("%d %d\n",l,r);
if(dp[l][r]!=0) return dp[l][r];
if(l==r) {dp[l][r]=1;return 1;}
int mi=100000;
for(int i=l;i<r;i++)
{
mi=min(mi,Dp(l,i)+Dp(i+1,r));//找到最小的哪一个
}
// printf("%d\n",mi);
int k=judge(l,r);//注意一下自己还可以压缩就ok啦
if(k){
int pos=(r-l+1)/k;
dp[l][r]=min(mi,dp[l][l+k-1]+getsum(pos)+2);//状态转移
}
else
dp[l][r]=mi;//发现自己不能压缩那就老老实实找到最小值吧
return dp[l][r];
}
int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
memset(dp,0,sizeof(dp));
scanf("%s",s+1);
n=strlen(s+1);
// int m=judge(1,n);
printf("%d\n",Dp(1,n));
}
return 0;
}