您的位置:首页 > 其它

多校联合1004,hdu3832

2011-07-13 22:51 197 查看
开始想用深搜做,但后面担心超时,再加上喵呜一直说用DP,就改用DP。dp[i][j][k]表示原字符串位置i,目标字符位置j,后面全变为k的最小操作次数。。。注意,这样的N维的初值不要只赋一个,要赋一维。。。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;

char s[510],s1[510];
int num,len,len1,dp[510][510][60];
int Cal(char ch)//字母返回序号
{
if(ch>='a'&&ch<='z') return ch-'a'+1;
else return ch-'A'+27;
}
char C(int k)//序号返回字母
{
if(k<27) return 'a'+k-1;
else return 'A'+k-27;
}

int main()
{
int i,j,k,ii,jj;
char ch;
while(scanf("%s",s1)!=EOF)
{
if(!strcmp(s1,"#")) break;
scanf("%s",s);
len=strlen(s);
len1=strlen(s1);

memset(dp,-1,sizeof(dp));
for(i=0;i<=len;i++)//(0,i)前面弄好了
dp[0][i][0]=i;
for(i=0;i<len1;i++)
dp[i][0][0]=i;
for(i=1;i<=len1;i++)//i对着j,前面已经弄好了
{
//	printf("%d ",i);
for(j=1;j<=len;j++)
{
for(k=0;k<53;k++)
{
if(!k) ch=s1[i-1];
else ch=C(k);
//后面全为k
if(k&&ch==s[j-1])
{
jj=11000000;
for(ii=0;ii<53;ii++)
if(ii!=k&&dp[i-1][j-1][ii]!=-1&&dp[i-1][j-1][ii]<jj)
jj=dp[i-1][j-1][ii];
if(jj==11000000) continue;
if(dp[i][j][k]==-1||dp[i][j][k]>jj+1)
dp[i][j][k]=jj+1;
}
//直接相等
if(ch==s[j-1]&&dp[i-1][j-1][k]!=-1&&(dp[i][j][k]==-1||dp[i][j][k]>dp[i-1][j-1][k]))
dp[i][j][k]=dp[i-1][j-1][k];
//改变一个
if(ch!=s[j-1]&&dp[i-1][j-1][k]!=-1&&(dp[i][j][k]==-1||dp[i][j][k]>dp[i-1][j-1][k]+1))
dp[i][j][k]=dp[i-1][j-1][k]+1;
//加一个
if(dp[i-1][j][k]!=-1&&(dp[i][j][k]==-1||dp[i][j][k]>dp[i-1][j][k]+1))
dp[i][j][k]=dp[i-1][j][k]+1;
//删一个
if(dp[i][j-1][k]!=-1&&(dp[i][j][k]==-1||dp[i][j][k]>dp[i][j-1][k]+1))
dp[i][j][k]=dp[i][j-1][k]+1;
//		printf("%d ",dp[i+1][j+1][k]);
}
//		printf("\n");
}
//	printf("\n");
}

for(i=1110000,k=0;k<53;k++)
if(dp[len1][len][k]!=-1&&dp[len1][len][k]<i)
i=dp[len1][len][k];
printf("%d\n",i);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: