您的位置:首页 > 其它

acdream1231(LCS变形+贪心)

2016-06-27 13:33 302 查看
链接:点击打开链接

题意:给出一些字母两两匹配的值,给出两个串,要求再求出两个串使给出的两个串是这两个串的子序列并且匹配值最小

代码:

#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
char s1[2005],s2[2005],s3[2005];
int in[2005],out[2005],val[2005][2005],dp[2005][2005],next[2005][2005];
int main(){                                     //和poj1080几乎一样,就是加了一个路径输出
int i,j,k,l1,l2,l3,tmp,tmp1,tmp2,tmp3,num;  //http://blog.csdn.net/stay_accept/article/details/51509685
while(scanf("%s%s%s",s3+1,s1+1,s2+1)!=EOF){
vector<char> a1,a2;
l1=strlen(s1+1);
l2=strlen(s2+1);
l3=strlen(s3+1);
memset(in,-1,sizeof(in));
memset(out,-1,sizeof(out));
memset(val,INF,sizeof(val));
for(i=1;i<=l3;i++){
for(j=1;j<=l3;j++){
scanf("%d",&num);
val[(int)s3[i]][(int)s3[j]]=num;
if(in[(int)s3[i]]==-1||val[(int)s3[i]][in[(int)s3[i]]]>val[(int)s3[i]][(int)s3[j]])
in[(int)s3[i]]=(int)s3[j];
if(out[(int)s3[j]]==-1||val[out[(int)s3[j]]][(int)s3[j]]>val[(int)s3[i]][(int)s3[j]])
out[(int)s3[j]]=(int)s3[i];
}
}                                       //求出每个字母与哪一个字母匹配值最小
dp[0][0]=0;                             //和被匹配时值最小
for(i=1;i<=l1;i++){
dp[i][0]=dp[i-1][0]+val[(int)s1[i]][in[(int)s1[i]]];
next[i][0]=1;
}
for(i=1;i<=l2;i++){
dp[0][i]=dp[0][i-1]+val[out[(int)s2[i]]][(int)s2[i]];
next[0][i]=2;
}                                       //先初始化
for(i=1;i<=l1;i++){
for(j=1;j<=l2;j++){                 //dp[i][j]表示第一个串匹配到i,第二个串匹配到j
tmp1=dp[i-1][j]+val[(int)s1[i]][in[(int)s1[i]]];
tmp2=dp[i][j-1]+val[out[(int)s2[j]]][(int)s2[j]];
tmp3=dp[i-1][j-1]+val[(int)s1[i]][(int)s2[j]];
tmp=min(tmp1,min(tmp2,tmp3));
dp[i][j]=tmp;
if(tmp==tmp1)
next[i][j]=1;
else if(tmp==tmp2)
next[i][j]=2;
else
next[i][j]=3;                   //并记录前驱
}
}
printf("%d\n",dp[l1][l2]);
while(l1>0||l2>0){
if(next[l1][l2]==1){
a1.push_back(s1[l1]);
a2.push_back((char)in[(int)s1[l1]]);
l1--;
}
else if(next[l1][l2]==2){
a1.push_back((char)out[(int)s2[l2]]);
a2.push_back(s2[l2]);
l2--;
}
else if(next[l1][l2]==3){
a1.push_back(s1[l1]);
a2.push_back(s2[l2]);
l1--,l2--;
}
}
for(i=a1.size()-1;i>=0;i--)
printf("%c",a1[i]);
printf("\n");
for(i=a2.size()-1;i>=0;i--)
printf("%c",a2[i]);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: