记录编号 137892 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 神奇的压缩机 最终得分 100
用户昵称 Gravatar清羽 是否通过 通过
代码语言 C++ 运行时间 0.135 s
提交时间 2014-11-05 13:40:51 内存使用 0.36 MiB
显示代码纯文本
//by tsingyawn
/*
动态规划问题
状态定义:d[i]表示1~i压缩所付出的最小内存代价
状态转移方程:d[i]=min(d[i],d[i-1]+w1);
			  d[i]=min(d[i],d[k-1]+w2);
			  第二种转移需满足judge(k)>=i-k+1;
judge(i)表示从i开始如果可以复制的最大长度。judge可在预处理时计算
边界:d[0]=0,其余为INF。
*/
#include<cstdio>
#include<ctime>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int maxn=5000;

char s[maxn];
int d[maxn],w1,w2,n,judge[maxn];

void init()
{

	scanf("%s%d%d",s,&w1,&w2);
	n=strlen(s);
	memset(judge,0,sizeof(judge));
	for(int i=0;i<n;i++)//起点
	    for(int j=0;j<i;j++){//被复制的字符串起点
			int k=j,tot=0;
			while(i+tot<n && s[k]==s[i+tot]){
				tot++;
				k++;
				if(k>=i) k=j;
			}
			judge[i]=max(judge[i],tot);
	    }
}

void work()
{
	for(int i=0;i<n;i++){
		d[i]=(i==0)?w1:w1+d[i-1];
		for(int k=0;k<i;k++){
			if(judge[k]<i-k+1) continue;
			if(k!=0) d[i]=min(d[i],d[k-1]+w2);
			else d[i]=min(d[i],w2);
		}
//		printf("d[%d]=%d\n",i,d[i]);
	}
	printf("%d\n",d[n-1]);
}

int main()
{
	freopen("WinCHG.in","r",stdin);
	freopen("WinCHG.out","w",stdout);
	init();
	work();
	fclose(stdin);
	fclose(stdout);
	return 0;
}