对于一个最有的串S,它可能是N(S')这种形式,还可能是两个最有串连接成的。此题只要注意最优解的递归结构就可以了。搞了很长时间==!
/*
* zoj-1554 folding.c
* 2012-5-28
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_SIZE 128
#define nMIKE_DISP_OPT
#define nMIKE_DISP_REC
int opt[MAX_SIZE][MAX_SIZE];
int rec[MAX_SIZE][MAX_SIZE];
char str[MAX_SIZE];
int length;
int disp(int start, int end)
{
int k=rec[start][end], i;
if(start==end)
putchar(str[start]);
else if(k>=0)
disp(start,k), disp(k+1,end);
else
{
printf("%d(",(end-start+1)/(-k));
disp(start,start-k-1);
printf(")");
}
return 0;
}
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("folding.in","r",stdin);
#endif
int i,j,start,end,len,_min,_rec,flag,step,tmp;
char ch;
while(scanf("%s",str)!=EOF)
{
/* init */
memset(opt,0,sizeof(opt));
memset(rec,0,sizeof(rec));
length=strlen(str);
for(i=0;i<length;i++)
opt[i][i]=1;
/* DP */
for(step=2; step<=length; step++)
{
for(start=0; start+step-1<length; start++)
{
/* A B -> AB */
_min=step;
_rec=start;
end=start+step-1;
for(i=start; i+1<=end; i++)
{
tmp=opt[start][i]+opt[i+1][end];
if(tmp<_min)
_min=tmp, _rec=i;
}
opt[start][end]=_min;
rec[start][end]=_rec;
/* A A A A -> 4(A) */
for(len=1; 2*len<=step; len++)
if(step%len==0)
{
flag=1;
for(i=start; i<start+len && flag; i++)
for(j=i, ch=str[i]; j<=end && flag; j+=len)
if(str[j]!=ch)
flag=0;
if(flag)
break;
}
if(flag)
{
_min=opt[start][start+len-1]+2+1;
if(step/len>=10)
_min++;
if(step/len>=100)
_min++;
if(opt[start][end]>_min)
opt[start][end]=_min, rec[start][end]=-len; /* attentino! */
}
}
}
/* display*/
#ifdef MIKE_DISP_OPT
puts("opt:");
for(i=0;i<length;i++)
for(j=0;j<length;j++)
printf("%d%c",opt[i][j],j==length-1?'\n':' ');
#endif
#ifdef MIKE_DISP_REC
puts("rec:");
for(i=0;i<length;i++)
for(j=0;j<length;j++)
printf("%d%c",rec[i][j],j==length-1?'\n':' ');
#endif
disp(0,length-1);
putchar('\n');
}
return 0;
}
8270

被折叠的 条评论
为什么被折叠?



