您的位置:首页 > 其它

UVA 1351 UVALive 3363 String Compression

2013-08-06 20:54 176 查看
dp[i][j] 表示  i-j这一段的最小值,

那么转移方程   dp[i][j]  =  min(dp[i][i+k]+dp[i+k+1][ j]           ,(如果是i--i+k-1  这个子串的重复)min( dp[i][i+k-1]    + flag+2      )  flag 为数字的长度  所占位数  )

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
#define clr(a, x) memset(a, x, sizeof(a))
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)

const int maxn = 220;
const int inf = 0x7f7f7f7f;
int dp[maxn][maxn];
string str;
int ok(int i,int j,int k)
{
//printf("i=%d j=%d k=%d ",i,j,k);
// cout<<str.substr(i,j-i+1)<<endl;
string tmp=str.substr(i,k);
// cout<<tmp<<endl;
int n=0;
for(i;i+k-1<=j;i+=k)
{
// cout<<"sub "<<str.substr(i,k)<<endl;
if(tmp==str.substr(i,k)) n++;
else return 0;
}
// int n=(j-i+1)/k;
int res=0;
while(n)
{
res++;
n/=10;
}
return res;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cin>>str;
int len=str.length();
for(int i=0;i<=len;i++)
{
for(int j=i;j<=len;j++)
dp[i][j]=inf;
dp[i][i]=1;
}
for(int i=0;i<len;i++)
{
for(int j=i-1;j>=0;j--)
{
dp[j][i]=i-j+1;
int tmp=inf;
for(int k=j;k<i;k++)
{
tmp=min(tmp,dp[j][k]+dp[k+1][i]);
}
for(int k=1;k<=i-j+1;k++)
{
if((i-j+1)%k==0)
{
int flag=ok(j,i,k);
// printf("ok i=%d j=%d f=%d\n",j,i,flag);
if(flag) tmp=min(tmp,dp[j][j+k-1]+flag+2);
}
}
//printf("i=%d j=%d tm=%d\n",j,i,tmp);
dp[j][i]=min(dp[j][i],tmp);
//printf("i=%d j=%d dp=%d\n",j,i,dp[j][i]);
}
}
printf("%d\n",dp[0][len-1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: